home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / lsof < prev    next >
Encoding:
Internet Message Format  |  1991-12-02  |  99.4 KB

  1. Subject:  v25i002:  lsof - a successor to fstat and ofiles
  2. Newsgroups: comp.sources.unix
  3. Approved: vixie@pa.dec.com
  4.  
  5. Submitted-by: Victor A Abell <abe@mace.cc.purdue.edu>
  6. Posting-number: Volume 25, Issue 2
  7. Archive-name: lsof
  8.  
  9. Lsof (for LiSt Open Files) lists files opened by processes on selected
  10. Unix systems.  It is my answer to those who regularly ask me when I am
  11. going to make fstat (comp.sources.unix volume 18, number 107) or ofiles
  12. X(volume 18, number 57) available on SunOS 4.1.1 or the like.
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of shell archive."
  21. # Contents:  00DIST 00README Makefile lsof.8 lsof.c sys sys/fss.h
  22. # Wrapped by vixie@cognition.pa.dec.com on Mon Dec  2 21:33:09 1991
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f '00DIST' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'00DIST'\"
  26. else
  27. echo shar: Extracting \"'00DIST'\" \(1564 characters\)
  28. sed "s/^X//" >'00DIST' <<'END_OF_FILE'
  29. X    Notes for the comp.sources.unix distribution of lsof 1.0
  30. X
  31. Lsof (for LiSt Open Files) lists files opened by processes on selected
  32. Unix systems.  It is my answer to those who regularly ask me when I am
  33. going to make fstat (comp.sources.unix volume 18, number 107) or ofiles
  34. X(volume 18, number 57) available on SunOS 4.1.1 or the like.
  35. X
  36. Lsof is a complete redesign of the fstat/ofiles series, based on the SunOS
  37. vnode model.  Thus, it has been tested on AIX 3.1.[357], HP-UX [78].x,
  38. NeXTStep 2.[01], Sequent Dynix 3.0.12 and 3.1.2, and Sunos 4.1 and 4.1.1.
  39. Using available kernel access methods, such as nlist() and kvm_read(),
  40. lsof reads process table entries, user areas and file pointers to reach
  41. the underlying structures that describe files opened by processes.
  42. X
  43. Lsof interprets most vnode extensions -- cdrnodes, fifonodes, gnodes,
  44. inodes, rnodes, snodes and tmpnodes.  It understands NFS connections.  It
  45. recognizes FIFOs, multiplexed files, Unix and Internet sockets.
  46. X
  47. Lsof accepts options to limit and filter its output.  That output describes
  48. the process that has opened the file, the command the process is executing,
  49. the owner of the process, the file descriptor of the file, and the file's
  50. device, inode number, size and file system name.  Additional special output
  51. is provided for special files -- e. g., the local and destination Internet
  52. addresses of Internet socket files.
  53. X
  54. Lsof may be used and distributed freely, subject to the limited conditions
  55. described in its source file.
  56. X
  57. Victor A. Abell
  58. Purdue University Computing Center
  59. November 22, 1991
  60. END_OF_FILE
  61. if test 1564 -ne `wc -c <'00DIST'`; then
  62.     echo shar: \"'00DIST'\" unpacked with wrong size!
  63. fi
  64. # end of '00DIST'
  65. fi
  66. if test -f '00README' -a "${1}" != "-c" ; then 
  67.   echo shar: Will not clobber existing file \"'00README'\"
  68. else
  69. echo shar: Extracting \"'00README'\" \(1524 characters\)
  70. sed "s/^X//" >'00README' <<'END_OF_FILE'
  71. X            Making and Installing lsof 1.0
  72. X
  73. The Makefile contains rules for making Makefile's for specific UNIX versions
  74. X-- e. g., ``make Makefile.sun''.  If none of the supplied rules fits your
  75. configuration, the Makefile has comments about the strings that you may need
  76. to change.  You may need to check your cpp documentation to see if the standard
  77. symbol that lsof.c assumes for your system is defined.  As an example, if the
  78. X``hpux'' symbol is defined by cpp, to compile lsof under HP-UX 8.x, you need
  79. to declare:
  80. X
  81. X    SYSDEFS = -DHPUX8
  82. X
  83. Set the following Makefile strings for installing lsof:
  84. X
  85. X    BIN        destination directory for the install rule
  86. X    CDEFS        compiler definitions
  87. X    DEBUG        compiler optimizations -- e. g., -g or -O
  88. X    DOC        destination directory for the PUCC-specific mkcat rule
  89. X    GRP        group (may need to be the group that can read
  90. X            /dev/kmem) (see MODE)
  91. X    LDLIB        special loader library -- e. g., -lkvm for SunOS
  92. X    MODE        0755 + 2000 if setgid access needed to /dev/kmem,
  93. X            and +4000 if any user should be able to search for
  94. X            any file, regardless of ownership or permissions
  95. X    SHELL        the shell make(1) should use -- usually /bin/sh
  96. X
  97. You may also have to change the install rule to use separate commands --
  98. cp, chown, chgrp, chmod -- if your system's install command does not honor
  99. Berkeley syntax.
  100. X
  101. If your HP-UX hp9000s800 system does not have the <sys/fss.h> header file
  102. add ``-I.'' to the CDEFS rule -- e. g.,
  103. X
  104. X    CDEFS= -I.
  105. X
  106. X
  107. Vic Abell <abe@mace.cc.purdue.edu>
  108. Purdue University Computing Center (PUCC)
  109. November 22, 1991
  110. END_OF_FILE
  111. if test 1524 -ne `wc -c <'00README'`; then
  112.     echo shar: \"'00README'\" unpacked with wrong size!
  113. fi
  114. # end of '00README'
  115. fi
  116. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  117.   echo shar: Will not clobber existing file \"'Makefile'\"
  118. else
  119. echo shar: Extracting \"'Makefile'\" \(3120 characters\)
  120. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  121. X#    $Id: Makefile,v 1.1 91/11/22 09:21:07 abe Exp $
  122. X#
  123. X#    Makefile for lsof(8L)
  124. X#
  125. X#    Victor A. Abell <abe@mace.cc.purdue.edu>
  126. X#    Purdue University Computing Center (PUCC)
  127. X
  128. X# Note: the following cpp (or equivalent) definitions are assumed.
  129. X#
  130. X#       AIX 3.1.[357]           -D_IBMR2
  131. X#       HP-UX 7.x               -Dhpux
  132. X#       HP-UX 8.x               -Dhpux
  133. X#       Purdue DYNIX 3.0.12     -DDYNIX
  134. X#       Sequent DYNIX 3.0.12    -DDYNIX
  135. X#       NeXTStep 2.1            -DNeXT
  136. X#       SunOS 4.1.1             -Dsun
  137. X#
  138. X# See SYSDEFS for other, specific definitions that may be required.
  139. X#
  140. X# Hint: see if there is a specific Makefile.<system> rule that is
  141. X#       suitable for your installation -- e. g., Makefile.hpux7 or
  142. X#       Makefile.sun.
  143. X
  144. X# Some make(1)'s need to be told explicitly what shell to use.
  145. X
  146. SHELL= /bin/sh
  147. X
  148. X# Define system-specific values in SYSDEFS.
  149. X#
  150. X#    System            Needs
  151. X#       HP-UX 7.x               SYSDEFS= -DHPUX7
  152. X#       HP-UX 8.x               SYSDEFS= -DHPUX8
  153. X#       Sequent DYNIX 3.0.12    SYSDEFS= -DSEQUENT
  154. X
  155. SYSDEFS=
  156. X
  157. BIN= ${DESTDIR}/usr/local/etc
  158. DOC= ${DESTDIR}/usr/man
  159. GRP= kmem
  160. X
  161. DEBUG= -O
  162. X
  163. X# If your HP-UX hp9000s800 system does not have the <sys/fss.h> header
  164. X# file, add ``-I.'' to CDEFS -- e. g.,
  165. X#
  166. X# CDEFS= -I.
  167. X
  168. CDEFS=
  169. X
  170. CFLAGS= ${DEBUG} ${CDEFS} ${SYSDEFS}
  171. X
  172. X# Define a special loader library.
  173. X#
  174. X#     System            Needs
  175. X#    HPUX7            LDLIB= -lBSD
  176. X#    SunOS            LDLIB= -lkvm
  177. X
  178. LDLIB=
  179. X
  180. HDR=
  181. SRC= lsof.c
  182. DEP= ${SRC}
  183. MAN= lsof.8
  184. OBJ= lsof.o
  185. SOURCE= Makefile ${HDR} ${SRC}
  186. X
  187. all: lsof
  188. X
  189. clean: FRC
  190. X    rm -f Makefile.* lsof *.o a.out core errs tags
  191. X
  192. X# The depend rule assumes the availability of PUCC's dependency generator.
  193. X
  194. depend: ${SRC} ${HDR} FRC
  195. X    maketd ${CDEFS} ${DEP}
  196. X
  197. install: lsof FRC
  198. X    install -c -s -m 2755 -g ${GRP} lsof ${BIN}
  199. X
  200. lint: ${SRC} ${HDR} FRC
  201. X    lint ${CDEFS} ${DEP}
  202. X
  203. lsof: ${OBJ}
  204. X    ${CC} -o $@ ${CFLAGS} ${OBJ} ${LDLIB}
  205. X
  206. X# Generate Makefile for IBM RISC/System 6000.
  207. X
  208. Makefile.ibmr2: Makefile
  209. X    sed -e 's@^GRP= kmem@GRP= system@' <Makefile >$@
  210. X
  211. X# Generate Makefile for HP-UX 7.x.
  212. X
  213. Makefile.hpux7: Makefile
  214. X    sed -e 's@^LDLIB=@LDLIB= -lBSD@' -e 's@^SYSDEFS=@SYSDEFS= -DHPUX7@' <Makefile >$@
  215. X
  216. X# Generate Makefile for HP-UX 8.x.
  217. X
  218. Makefile.hpux8: Makefile
  219. X    sed -e 's@^SYSDEFS=@SYSDEFS= -DHPUX8@' <Makefile >$@
  220. X
  221. X# Generate Makefile for NeXTStep 2.[01].
  222. X
  223. Makefile.next2: Makefile
  224. X    sed -e 's@^GRP= kmem@GRP= operator@' <Makefile >$@
  225. X
  226. X# Generate Makefile for Sequent's version of DYNIX.
  227. X
  228. Makefile.sequent: Makefile
  229. X    sed -e 's@^SYSDEFS=@SYSDEFS= -DSEQUENT@' <Makefile >$@
  230. X
  231. X# Generate Makefile for SunOS 4.1.1.
  232. X
  233. Makefile.sun: Makefile
  234. X    sed -e 's@^LDLIB=@LDLIB= -lkvm@' <Makefile >$@
  235. X
  236. X# The mkcat rule assumes the availability of PUCC's manual page handler.
  237. X
  238. mkcat: ${MAN} ${DOC} FRC
  239. X    mkcat -r${DOC} ${MAN}
  240. X
  241. print: source FRC
  242. X    lpr -J'lsof source' ${SOURCE}
  243. X
  244. source: ${SOURCE} FRC
  245. X
  246. X# The following rule assumes the use of RCS.
  247. X
  248. spotless: clean
  249. X    rcsclean ${SOURCE}
  250. X
  251. tags: ${SRC} ${HDR} FRC
  252. X    ctags -t ${SRC} ${HDR}
  253. X
  254. X# The following rule assumes the use of RCS.
  255. X
  256. X${SOURCE}:
  257. X    co -q $@
  258. X
  259. XFRC:
  260. X
  261. X# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
  262. X
  263. lsof.o: lsof.c
  264. X
  265. X# *** Do not add anything here - It will go away. ***
  266. END_OF_FILE
  267. if test 3120 -ne `wc -c <'Makefile'`; then
  268.     echo shar: \"'Makefile'\" unpacked with wrong size!
  269. fi
  270. # end of 'Makefile'
  271. fi
  272. if test -f 'lsof.8' -a "${1}" != "-c" ; then 
  273.   echo shar: Will not clobber existing file \"'lsof.8'\"
  274. else
  275. echo shar: Extracting \"'lsof.8'\" \(8577 characters\)
  276. sed "s/^X//" >'lsof.8' <<'END_OF_FILE'
  277. X.TH LSOF 8 PUCC
  278. X.if !\n()P .nr )P 1v
  279. X.SH NAME
  280. lsof \- list open files
  281. X.SH SYNOPSIS
  282. X.B lsof
  283. X[
  284. X.B \-d
  285. X] [
  286. X.B \-h
  287. X] [
  288. X.B \-l
  289. X] [
  290. X.B \-n
  291. X] [
  292. X.B \-N
  293. X] [
  294. X.BI \-p " l"
  295. X] [
  296. X.B \-s
  297. X] [
  298. X.B \-t
  299. X] [
  300. X.BI \-u " l"
  301. X] [
  302. X.BI \-U
  303. X]
  304. X.I names
  305. X.SH DESCRIPTION
  306. X.I Lsof
  307. lists information about files opened by processes for the following
  308. operating systems:
  309. X.PP
  310. X.nf
  311. X    AIX 3.1.3, 3.1.5 and 3.1.7 for the IBM RISC/System 6000
  312. X    Dynix 3.0.12 and 3.1.2 for the Sequent Symmetry S81
  313. X    HP\-UX 7.x for the Hewlett Packard 9000/300 and 9000/800
  314. X    HP\-UX 8.x for the Hewlett Packard 9000/300, 9000/700 and 9000/800
  315. X    NeXTStep 2.0 and 2.1 for the NeXT Work Station
  316. X    SunOS 4.1.1
  317. X.fi
  318. X.PP
  319. An open file may be a regular file, a directory, a character special
  320. file, or a network file (Internet socket, NFS file or Unix domain socket.)
  321. A specific file may be selected by its path
  322. X.IR name .
  323. X.SH OPTIONS
  324. In the absence of any options,
  325. X.I lsof
  326. lists all open files belonging to all active processes.
  327. X.PP
  328. If any list request option is specified, all other lists must be
  329. specifically requested \- e. g., if
  330. X.B \-n
  331. is specified for the listing of Internet network files, NFS files won't be
  332. listed unless
  333. X.B \-N
  334. is also specified;
  335. or if a user list is specified with the
  336. X.B \-u
  337. option, Internet network files and Unix domain socket files belonging to
  338. users not in the list won't be listed unless the
  339. X.B \-n
  340. and
  341. X.B \-U
  342. options are also specified.
  343. X.TP \w'names'u+4
  344. X.B \-d
  345. This option selects the production of error messages about unreadable
  346. subdirectories of the
  347. X.I /dev
  348. directory.
  349. Under SunOS, for example, the
  350. X.I /dev/lpd
  351. subdirectory is unreadable for security reasons.
  352. When building its cache of names and device numbers for devices,
  353. X.I lsof
  354. skips unreadable subdirectories silently unless
  355. X.B \-d
  356. is specified.
  357. X.TP
  358. X.B \-h
  359. This option selects a brief usage (help) output list.
  360. X.TP
  361. X.B \-l
  362. This option inhibits the conversion of user ID numbers to login names.
  363. X.TP
  364. X.B \-n
  365. This option selects the listing of Internet network files.
  366. X.TP
  367. X.B \-N
  368. This option selects the listing of NFS files.
  369. X.TP
  370. X.BI \-p " l"
  371. This option selects the listing of files for the processes whose ID numbers
  372. are in the comma\-separated list `l' \- e. g., ``123'' or ``123,456''.
  373. X(There should be no spaces in the list.)
  374. X.TP
  375. X.B \-s
  376. This option removes the SIZE column from the output, shortening
  377. output lines by nine characters.
  378. X.TP
  379. X.B \-t 
  380. This option specifies that
  381. X.I lsof
  382. should produce terse output with process identifiers only and no header \-
  383. e. g., so that the output may be piped to
  384. X.IR kill (1).
  385. X.TP
  386. X.BI \-u " l"
  387. This option selects the listing of files for the user whose login names
  388. or user ID numbers are in the comma\-separated list `l' \- e. g., ``abe'',
  389. or ``548,root''.
  390. X(There should be no spaces in the list.)
  391. X.TP
  392. X.B \-U
  393. This option selects the listing of Unix domain socket files.
  394. X.TP
  395. X.I names
  396. These are path names of specific files to list.
  397. Symbolic links are resolved before use.
  398. X.IP
  399. If a
  400. X.I name 
  401. is the mount point of a file system or the device of the mount point of a
  402. file system,
  403. X.I lsof
  404. will list all the files open on the file system.
  405. If a
  406. X.I name
  407. is the base name of a family of multiplexed files \- e. g, AIX's
  408. X.IR /dev/pts " \-"
  409. X.I lsof
  410. will list all the associated multipled files on the device that
  411. are open \- e. g.,
  412. X.IR /dev/pts/1 ,
  413. X.IR /dev/pts/2 ,
  414. etc.
  415. X.IP
  416. If a
  417. X.I name
  418. is none of the above,
  419. X.I lsof
  420. will list any open files whose device and inode match that of the
  421. specified path
  422. X.IR name .
  423. X.SH OUTPUT
  424. X.I Lsof
  425. lists for each open file:
  426. X.TP \w'COMMAND'u+4
  427. COMMAND
  428. contains the first nine characters of the name of the Unix command associated
  429. with the process.
  430. X.TP
  431. PID
  432. is the Process IDentification number of the process.
  433. X.TP
  434. USER
  435. is the user ID number or login name of the user to whom the process
  436. belongs.
  437. X(See the
  438. X.B \-l
  439. option.)
  440. X.TP
  441. XFD
  442. is the File Descriptor number of the file or ``cwd'' if it is the
  443. current working directory of the process.
  444. XFD is followed by these characters for file locks:
  445. X.IP
  446. X    \fBr\fP for read lock on part of the file;
  447. X.br
  448. X    \fBR\fP for a read lock on the entire file;
  449. X.br
  450. X    \fBw\fP for a write lock on part of the file;
  451. X.br
  452. X    \fBW\fP for a write lock on the entire file.
  453. X.TP
  454. TYPE
  455. is the type of the vnode associated with the file (see <sys/vnode.h>);
  456. X.IP
  457. or ``inet'' for an Internet domain socket;
  458. X.IP
  459. or ``unix'' for a Unix domain socket.
  460. X.TP
  461. DEVICE
  462. contains the major and minor device numbers for a character special, block
  463. special, regular, directory or NFS file (an HP\-UX minor device number is
  464. listed in hexadecimal);
  465. X.IP
  466. or the protocol control block address of a Unix or Internet domain file
  467. X(the number that appears in
  468. X.IR netstat (1)'s
  469. X.B \-A
  470. output).
  471. X.TP
  472. SIZE
  473. is the size of the file in bytes, when it is known.
  474. This column may be removed from the output by specifying the
  475. X.B \-s
  476. option.
  477. X.TP
  478. INODE
  479. is the inode number of a local file;
  480. X.IP
  481. or the inode number of an NFS file in the server host;
  482. X.IP
  483. or the Internet protocol type \- e. g, ``TCP''.
  484. X.TP
  485. NAME
  486. is the name of the mount point and file system on which the file resides;
  487. X.IP
  488. or the name of a file specified in the
  489. X.I names
  490. option (after any symbolic links have been resolved);
  491. X.IP
  492. or the name of a character special or block special device;
  493. X.IP
  494. or the local and remote Internet addresses of a network file;
  495. X.IP
  496. or the address of a Unix domain socket;
  497. X.IP
  498. or the local and remote mount point names of an NFS file.
  499. X.SH DIAGNOSTICS
  500. XErrors are identified with messages on the standard error file.
  501. X.PP
  502. X.I Lsof
  503. returns a one (1) if any error was detected, including the failure to
  504. locate any
  505. X.IR names .
  506. It returns a zero (0) if no errors were detected and if it was able to
  507. list information about all the specified
  508. X.IR names .
  509. X.SH EXAMPLES
  510. To list all open files, use:
  511. X.IP
  512. lsof
  513. X.PP
  514. To list all open Internet and Unix domain files, use:
  515. X.IP
  516. lsof -n -U
  517. X.PP
  518. To list all open files for login name ``abe'', user ID 1234, process 123,
  519. process 456 and process 789, use:
  520. X.IP
  521. lsof -p 789,456,123 -u 1234,abe
  522. X.PP
  523. To list all open files on device /dev/hd4, use:
  524. X.IP
  525. lsof /dev/hd4
  526. X.PP
  527. To find the process that has /u/abe/foo open, use:
  528. X.IP
  529. lsof /u/abe/foo
  530. X.PP
  531. To send a SIGHUP to the processes that have /u/abe/bar open, use:
  532. X.IP
  533. kill -HUP `lsof -t /u/abe/bar`
  534. X.SH BUGS
  535. Since
  536. X.I lsof
  537. reads kernel memory in its search for open files, rapid changes in kernel
  538. memory may produce unpredictable results.
  539. X.PP
  540. Absence of hardware or software configurations for some operating systems
  541. X\- e. g., HP\-UX 7.x and 8.x and Sequent Dynix 3.1.2 \- means that
  542. X.I lsof
  543. has not been fully tested on them.
  544. X.PP
  545. The lock status character (following the file descriptor) is derived under
  546. AIX from a test of only the first filock structure of the gnode
  547. X(see <sys/flock.h> and <sys/gnode.h>).
  548. X.PP
  549. X.I Lsof
  550. can't search for any file by
  551. X.I name
  552. unless it is installed with root set-UID permission.
  553. Otherwise it is restricted to searching for files to which its user
  554. or its set-GID group (if any) have access.
  555. X.PP
  556. X.I Lsof
  557. startup time is long on systems where scanning the
  558. X.I /dev
  559. directory is a slow operation.
  560. X.PP
  561. Output lines are sometimes greater than eighty characters \- e. g.,
  562. for completed Internet connections or NFS files \- causing the output
  563. listing to be irregularly spaced.
  564. The
  565. X.B \-s
  566. option may be specified to remove the SIZE column, shortening output
  567. lines by nine characters.
  568. X.PP
  569. If there are files or subdirectories in
  570. X.I /dev
  571. that
  572. X.I lsof
  573. can't
  574. X.IR stat (2)
  575. or read, it will ignore them without complaint, unless the
  576. X.B \-d
  577. option is selected.
  578. Whether
  579. X.I lsof
  580. complains or not, it is unable to report major and minor device numbers
  581. for the entries it can't access.
  582. X.SH FILES
  583. X.TP \w'/dev/swap'u+16
  584. X/dev/drum    system paging device
  585. X.TP
  586. X/dev/kmem    kernel virtual memory device
  587. X.TP
  588. X/dev/mem    physical memory device
  589. X.TP
  590. X/dev/swap    system paging device
  591. X.SH AUTHORS
  592. X.I Lsof
  593. was written by Victor A. Abell of the Purdue University Computing Center
  594. X(PUCC), based on the
  595. X.I fstat
  596. and
  597. X.I ofiles
  598. programs.
  599. He acknowledges his debt to the work of Dan Bernstein, Michael ``Ford''
  600. Ditto, Tom Dunigan, Alexander Dupuy, Vik Lall, Ray Moody, C. Spencer,
  601. Michael Spitzer and those who wrote Berkeley's
  602. X.I fstat
  603. program, all contributors to
  604. X.I lsof's
  605. predecessors.
  606. He thanks Doug McKenzie for his HP\-UX
  607. X.I proctor
  608. program and Rich Kulawiec for pointing it out.
  609. XFinally, he is grateful to Jim Cooper, J. Nelson Howell, Markus
  610. Lautenbacher, Wendy Lin, Andreas Luik, Fletcher Mattox, Michael Mackenzie,
  611. Jeff Stewart and Patrick Wolfe for their help in developing and
  612. improving
  613. X.IR lsof .
  614. X.SH SEE ALSO
  615. ff(1),
  616. fstat(8),
  617. fuser(1),
  618. kill(1),
  619. netstat(1),
  620. ofiles(8L),
  621. ps(1).
  622. lsof.8
  623. END_OF_FILE
  624. if test 8577 -ne `wc -c <'lsof.8'`; then
  625.     echo shar: \"'lsof.8'\" unpacked with wrong size!
  626. fi
  627. # end of 'lsof.8'
  628. fi
  629. if test -f 'lsof.c' -a "${1}" != "-c" ; then 
  630.   echo shar: Will not clobber existing file \"'lsof.c'\"
  631. else
  632. echo shar: Extracting \"'lsof.c'\" \(79705 characters\)
  633. sed "s/^X//" >'lsof.c' <<'END_OF_FILE'
  634. X/*
  635. X *    lsof.c - list open files
  636. X */
  637. X
  638. X
  639. X/*
  640. X *    Lsof lists files opened by processes of:
  641. X *
  642. X *        AIX 3.1.[357]        (#define _IBMR2)
  643. X *        Purdue DYNIX 3.0.12    (#define DYNIX)
  644. X *        Sequent DYNIX 3.0.12    (#define DYNIX, #define SEQUENT)
  645. X *        Sequent DYNIX 3.1.2    (#define DYNIX31)
  646. X *        HP-UX 7.x        (#define hpux, #define HPUX7)
  647. X *        HP-UX 8.x        (#define hpux, #define HPUX8)
  648. X *        NeXTStep 2.[01]        (#define NeXT)
  649. X *        SunOS 4.1.1        (#define sun)
  650. X */
  651. X
  652. X/*
  653. X * Copyright 1991 Purdue Research Foundation, West Lafayette, Indiana
  654. X * 47907.  All rights reserved.
  655. X *
  656. X * Written by Victor A. Abell
  657. X *
  658. X * This software is not subject to any license of the American Telephone
  659. X * and Telegraph Company or the Regents of the University of California.
  660. X *
  661. X * Permission is granted to anyone to use this software for any purpose on
  662. X * any computer system, and to alter it and redistribute it freely, subject
  663. X * to the following restrictions:
  664. X *
  665. X * 1. Neither the author nor Purdue University are responsible for any
  666. X *    consequences of the use of this software.
  667. X *
  668. X * 2. The origin of this software must not be misrepresented, either by
  669. X *    explicit claim or by omission.  Credit to the author and Purdue
  670. X *    University must appear in documentation and sources.
  671. X *
  672. X * 3. Altered versions must be plainly marked as such, and must not be
  673. X *    misrepresented as being the original software.
  674. X *
  675. X * 4. This notice may not be removed or altered.
  676. X */
  677. X
  678. X#if    !defined(lint)
  679. static char copyright[] =
  680. X"@(#) Copyright 1991 Purdue Research Foundation.\nAll rights reserved.\n";
  681. X#endif
  682. X
  683. static char Version[] = "1.0";
  684. X
  685. X
  686. X/*
  687. X *    Usage:
  688. X *
  689. X *        lsof [-d] [-h] [-l] [-n] [-N] [-p l] [-s] [-t] [-u l] [-U] [names]
  690. X *
  691. X *    where:
  692. X *
  693. X *        -d    Issue error messages about unreadable /dev
  694. X *            subdirectories.
  695. X *
  696. X *        -h    List help.
  697. X *
  698. X *        -l    Do not convert User ID numbers to login names.
  699. X *
  700. X *        -n    List Internet network files.
  701. X *
  702. X *        -N    List NFS files.
  703. X *
  704. X *        -p l    List files for Process IDentifier list l -- comma
  705. X *            separated list of numbers.
  706. X *
  707. X *        -s    Do not display file size.
  708. X *
  709. X *        -t    List terse output -- i. e., Process ID numbers without
  710. X *            a header.
  711. X *
  712. X *        -u l    List files for user list l -- comma separated list of
  713. X *            login names or User IDentification numbers.
  714. X *
  715. X *        -U    List Unix domain sockets.
  716. X *
  717. X *        names    are the path names of file systems, mount points,
  718. X *            devices and files to locate.
  719. X */
  720. X
  721. X#if    defined(NeXT) && !defined(MACH)
  722. X/*
  723. X * The definition of MACH for the NeXT is required for proper header
  724. X * file configuration -- i. e., some header files have ``#ifdef MACH''
  725. X * statements that affect the size of kernel structures.
  726. X */
  727. X
  728. X#define MACH    1
  729. X#endif
  730. X
  731. X#include <sys/types.h>
  732. X#include <sys/param.h>
  733. X
  734. X#include <ctype.h>
  735. X#include <errno.h>
  736. X#include <pwd.h>
  737. X#include <setjmp.h>
  738. X#include <stdio.h>
  739. X
  740. X#include <sys/domain.h>
  741. X#include <sys/mbuf.h>
  742. X#include <sys/protosw.h>
  743. X#include <sys/socket.h>
  744. X#include <sys/socketvar.h>
  745. X#include <sys/stat.h>
  746. X#include <sys/time.h>
  747. X#include <sys/un.h>
  748. X#include <sys/unpcb.h>
  749. X#include <sys/vfs.h>
  750. X#include <sys/vnode.h>
  751. X#include <net/route.h>
  752. X#include <netinet/in.h>
  753. X#include <netinet/in_pcb.h>
  754. X
  755. X#if    defined(DYNIX31)
  756. X#undef    SEQUENT
  757. X#undef    DYNIX
  758. X#define    DYNIX
  759. X#endif
  760. X
  761. X#if    defined(DYNIX)
  762. X#include <mntent.h>
  763. X#include <strings.h>
  764. X#include <nlist.h>
  765. X#include <nfs/nfs.h>
  766. X#include <nfs/nfs_clnt.h>
  767. X#include <nfs/rnode.h>
  768. X#include <sys/dir.h>
  769. X#include <sys/file.h>
  770. X#include <sys/proc.h>
  771. X#define KERNEL
  772. X#include <sys/file.h>
  773. X#include <sys/inode.h>
  774. X#include <ufs/mount.h>
  775. X#undef KERNEL
  776. X#include <sys/user.h>
  777. X
  778. X#if    !defined(DYNIX31)
  779. X/*
  780. X * This is from sys/user.h.  It's ifdef KERNEL, though, and defining
  781. X * KERNEL for user.h breaks other things.
  782. X *
  783. X * Open-file table extension object structure.
  784. X */
  785. X
  786. struct  ofile_ext {
  787. X    struct  ofile_ext *oe_next;             /* list of unused entries */
  788. X    short           oe_nofile;              /* # ofile entries */
  789. X    short           oe_refcnt;              /* # proc's sharing this ext */
  790. X    short           oe_ccount;              /* # sharing proc's in memory */
  791. X    swblk_t         oe_swaddr;              /* disk address when swapped */
  792. X    sema_t          oe_mutex;               /* misc mutex */
  793. X    struct  ofile   *oe_ofile;              /* array of open files */
  794. X};
  795. X#endif
  796. X
  797. X#endif
  798. X
  799. X#if    defined(hpux)
  800. X#include <stdlib.h>
  801. X#include <dirent.h>
  802. X#include <mntent.h>
  803. X#include <string.h>
  804. X#include <nlist.h>
  805. X#include <rpc/types.h>
  806. X#include <nfs/nfs.h>
  807. X#include <nfs/nfs_clnt.h>
  808. X#include <nfs/rnode.h>
  809. X#include <nfs/snode.h>
  810. X#include <sys/file.h>
  811. X#include <sys/inode.h>
  812. X
  813. X#if    defined(HPUX8)
  814. X#include <sys/pstat.h>
  815. X#endif
  816. X
  817. X#include <sys/resource.h>
  818. X#include <sys/proc.h>
  819. X#include <sys/vmmac.h>
  820. X#include <sys/user.h>
  821. X
  822. X/*
  823. X * This is from <sys/mount.h>, defined under the _KERNEL symbol.
  824. X * Unfortunately, defining _KERNEL causes <sys/mount.h> to include
  825. X * other header files not in <sys>.
  826. X */
  827. X
  828. struct mount {
  829. X    struct    mount *m_hforw;  /* forward hash pointer */
  830. X    struct    mount *m_hback;  /* backward hash pointer */
  831. X    struct    mount *m_rhforw; /* forward hash pointer for real device */
  832. X    struct    mount *m_rhback; /* backward hash pointer for real device */
  833. X    struct vfs    *m_vfsp; /* vfs structure for this filesystem */
  834. X    dev_t    m_dev;         /* device mounted */
  835. X   };
  836. X#endif
  837. X
  838. X#if    defined(_IBMR2)
  839. X#include <stdlib.h>
  840. X#include <string.h>
  841. X#include <dirent.h>
  842. X#if    !defined(_KERNEL)
  843. X#define _KERNEL    1
  844. X#endif
  845. X#include <sys/file.h>
  846. X#undef    _KERNEL
  847. X#include <sys/mntctl.h>
  848. X#include <sys/sysmacros.h>
  849. X#include <sys/vattr.h>
  850. X#include <sys/vmount.h>
  851. X#include <procinfo.h>
  852. X#include <nfs/rnode.h>
  853. X
  854. X/*
  855. X * AIX 3.1.[357] doesn't supply the necessary cdrnode.h.
  856. X */
  857. X
  858. struct cdrnode {
  859. X    caddr_t        f1[4];
  860. X    struct gnode    f2;
  861. X    dev_t        f3;
  862. X    ino_t        cn_inumber;    /* inode number */
  863. X    caddr_t        f4;
  864. X    cnt_t        f5[2];
  865. X    u_short        f6;
  866. X    uint        f7[2];
  867. X    uchar        f8[3];
  868. X    off_t        cn_size;    /* size of file in bytes */
  869. X};
  870. X#endif
  871. X
  872. X#if    defined(NeXT)
  873. X#include <c.h>
  874. X#include <stdlib.h>
  875. X#include <string.h>
  876. X#include <mntent.h>
  877. X#include <nlist.h>
  878. X#include <signal.h>
  879. X#include <kern/queue.h>
  880. X#include <sys/policy.h>
  881. X#if    !defined(NCPUS)
  882. X#define NCPUS    1
  883. X#endif
  884. X#include <kern/task.h>
  885. X#include <netinet/in.h>
  886. X#include <rpc/rpc.h>
  887. X#include <rpc/xdr.h>
  888. X#include <nfs/nfs.h>
  889. X#include <nfs/nfs_clnt.h>
  890. X#include <nfs/rnode.h>
  891. X#include <sys/dir.h>
  892. X#include <sys/domain.h>
  893. X#if    !defined(KERNEL)
  894. X#define KERNEL
  895. X#endif
  896. X#include <sys/file.h>
  897. X#undef  KERNEL
  898. X#include <ufs/mount.h>
  899. X#include <sys/protosw.h>
  900. X#include <sys/socket.h>
  901. X#include <sys/socketvar.h>
  902. X#include <sys/stat.h>
  903. X#include <sys/ucred.h>
  904. X#include <sys/un.h>
  905. X#include <sys/unpcb.h>
  906. X#if    !defined(SHOW_UTT)
  907. X#define SHOW_UTT
  908. X#endif
  909. X#include <sys/user.h>
  910. X#undef    SHOW_UTT
  911. X#include <sys/proc.h>
  912. X#include <sys/vfs.h>
  913. X#include <ufs/inode.h>
  914. X
  915. X/*
  916. X * The following substitution compensates for the snode.h that NeXT does
  917. X * not supply in NeXTStep 2.0 or 2.1.  The value of interest is s_realvp.
  918. X */
  919. X
  920. struct snode {
  921. X    struct    snode *s_next;        /* must be first */
  922. X    struct    vnode s_vnode;        /* vnode associated with this snode */
  923. X    struct    vnode *s_realvp;    /* vnode for the fs entry (if any) */
  924. X};
  925. X#endif
  926. X
  927. X#if    defined(sun)
  928. X#include <stdlib.h>
  929. X#include <string.h>
  930. X#include <dirent.h>
  931. X#include <kvm.h>
  932. X#include <mntent.h>
  933. X#include <nlist.h>
  934. X#include <signal.h>
  935. X#include <rpc/types.h>
  936. X#include <nfs/nfs.h>
  937. X#include <nfs/rnode.h>
  938. X#include <specfs/snode.h>
  939. X#include <sys/proc.h>
  940. X#include <sys/sysmacros.h>
  941. X#include <sys/user.h>
  942. X#include <tmpfs/tmpnode.h>
  943. X#include <ufs/inode.h>
  944. X#include <ufs/mount.h>
  945. X#if    !defined(KERNEL)
  946. X#define KERNEL    1
  947. X#endif
  948. X#include <sys/file.h>
  949. X#include <specfs/fifonode.h>
  950. X#undef    KERNEL
  951. X#endif
  952. X
  953. extern int errno;
  954. X
  955. extern struct passwd *getpwnam(), *getpwuid();
  956. X
  957. X#if    defined(DYNIX) || defined(sun)
  958. extern int nlist();
  959. X#endif
  960. X
  961. extern char *optarg;
  962. extern int optind;
  963. extern char *sys_errlist[];
  964. X
  965. X#define DEVINCR        1024    /* device table malloc() increment */
  966. X#define IPROTOL        5    /* Internet protocol length */
  967. X#define LOGINML        8    /* login name length */
  968. X#define PIDINCR        10    /* PID table malloc() increment */
  969. X#define STATTMO        5    /* stat() timeout in seconds */
  970. X#define UIDINCR        10    /* UID table malloc() increment */
  971. X#define USERPRTL    8
  972. X#define V_REG        0    /* vnode is regular */
  973. X#define V_FIFO        1    /* vnode is a FIFO */
  974. X#define V_NFS        2    /* vnode is an NFS file system */
  975. X#define V_STREAM    3    /* vnode is a stream */
  976. X#define V_TMP        4    /* vnode is a tmpfs */
  977. X
  978. X#if    defined(DYNIX)
  979. X#define MALLOC_P    char
  980. X#define FREE_P        MALLOC_P
  981. X#define MALLOC_S    unsigned
  982. X#define N_UNIX        "/dynix"
  983. X#define QSORT_P        char
  984. X#define STRNCPY_L    int
  985. X#define SWAP        "/dev/drum"
  986. X#define U_SIZE        sizeof(struct user)
  987. X
  988. X#if    defined(DYNIX31)
  989. X#define strchr        index
  990. X#define strrchr        rindex
  991. X#endif
  992. X
  993. X#if    defined(SEQUENT)
  994. X#define strchr        index
  995. X#define strrchr        rindex
  996. X#define    uid_t        int
  997. X#define    unp_addr    unp_remaddr
  998. X#endif
  999. X
  1000. X#endif
  1001. X
  1002. X#if    defined(hpux)
  1003. X#define MALLOC_P    char
  1004. X#define FREE_P        void
  1005. X#define MALLOC_S    unsigned
  1006. X#define MOUNTED        MNT_MNTTAB
  1007. X#define N_UNIX        "/hp-ux"
  1008. X#define PROCSIZE    sizeof(struct proc)
  1009. X#define QSORT_P        void
  1010. X#define STRNCPY_L    size_t
  1011. X#define SWAP        "/dev/swap"
  1012. X
  1013. X#if    defined(HPUX7)
  1014. X#define unp_addr    unp_locaddr
  1015. X/*
  1016. X * HP-UX 7.x SWAP must be read in DEV_BSIZE chunks.
  1017. X */
  1018. X#define U_SIZE        (((DEV_BSIZE+sizeof(struct user))/DEV_BSIZE)*DEV_BSIZE)
  1019. X#endif
  1020. X
  1021. X#if    defined(HPUX8)
  1022. X#define    U_SIZE        sizeof(struct user)
  1023. X#endif
  1024. X
  1025. X#endif
  1026. X
  1027. X#if    defined(_IBMR2)
  1028. X#define MALLOC_P    void
  1029. X#define FREE_P        MALLOC_P
  1030. X#define MALLOC_S    size_t
  1031. X#define PROCSIZE    sizeof(struct procinfo)
  1032. X#define QSORT_P        void
  1033. X#define STRNCPY_L    int
  1034. X#define U_SIZE        sizeof(struct user)
  1035. X#endif
  1036. X
  1037. X#if    defined(NeXT)
  1038. X#define MALLOC_P    void
  1039. X#define FREE_P        MALLOC_P
  1040. X#define MALLOC_S    size_t
  1041. X#define PROCSIZE    sizeof(struct proc)
  1042. X#define QSORT_P        void
  1043. X#define STRNCPY_L    int
  1044. X#define U_SIZE        sizeof(struct user)
  1045. X#if    !defined(VMUNIX)
  1046. X#define VMUNIX        "/mach"
  1047. X#endif
  1048. X#endif
  1049. X
  1050. X#if    defined(sun)
  1051. X#define CLONEMAJ    37    /* major device number for clone device */
  1052. X#define MALLOC_P    char
  1053. X#define FREE_P        MALLOC_P
  1054. X#define MALLOC_S    unsigned
  1055. X#define N_UNIX        "/vmunix"
  1056. X#define PROCSIZE    sizeof(struct proc)
  1057. X#define QSORT_P        char
  1058. X#define STRNCPY_L    int
  1059. X#define U_SIZE        sizeof(struct user)
  1060. X#endif
  1061. X
  1062. X
  1063. X/*
  1064. X * Global storage definitions
  1065. X */
  1066. X
  1067. X#if    defined(sun)
  1068. struct clone {
  1069. X    struct dev *dp;        /* pointer to device entry in Devtp[] */
  1070. X    struct clone *next;
  1071. X
  1072. X} *Clone = NULL;
  1073. X#endif
  1074. X
  1075. char *Command;            /* command name */
  1076. dev_t Dev;            /* device number */
  1077. char Devch[32];            /* alternate characters for device printing */
  1078. X
  1079. struct dev {
  1080. X    dev_t rdev;        /* device */
  1081. X    char *name;        /* name */
  1082. X
  1083. X} *Devtp = NULL;        /* device table pointer */
  1084. X
  1085. char Fd[8];            /* file descriptor for printing */
  1086. int Fdev = 0;            /* have device number flag */
  1087. int Fdevmsg = 0;        /* -d flag status */
  1088. int Fhelp = 0;            /* -h flag status */
  1089. int Fnet = 0;            /* -n flag status */
  1090. int Fnfs = 0;            /* -N flag status */
  1091. int Fprint = 0;            /* print line flag */
  1092. int Fsize = 1;            /* -s flag status */
  1093. int Fterse = 0;            /* -t flag status */
  1094. int Funix = 0;            /* -U flag status */
  1095. int Futol = 1;            /* -l flag status */
  1096. int Hdr = 0;            /* header print status */
  1097. long Inode = -1l;        /* inode number
  1098. X                 *    -1: none (don't print anything)
  1099. X                 *    -2: blank (print spaces) */
  1100. char Iproto[IPROTOL+1];        /* Internet protocol name */
  1101. X
  1102. X#if    defined(sun)
  1103. kvm_t *Kd;            /* kvm descriptor */
  1104. X#endif
  1105. X
  1106. int Kmem = -1;            /* /dev/kmem file descriptor */
  1107. X
  1108. struct l_vfs {
  1109. X
  1110. X    struct vfs *addr;    /* kernel address */
  1111. X
  1112. X#if    defined(DYNIX) || defined(hpux) || defined(_IBMR2)
  1113. X    dev_t dev;        /* device */
  1114. X#endif
  1115. X    char *dir;        /* mounted directory */
  1116. X    char *fsname;        /* file system name */
  1117. X
  1118. X#if    defined(_IBMR2)
  1119. X    int vmt_flags;        /* vmount flags */
  1120. X    int vmt_gfstype;    /* vmount gfs type */
  1121. X#endif
  1122. X
  1123. X    struct l_vfs *next;    /* next entry pointer */
  1124. X} *Lvfs = NULL;            /* local vfs structure table */
  1125. X
  1126. X#if    defined(HPUX7)
  1127. int Mem = -1;            /* /dev/mem file descriptor */
  1128. X#endif
  1129. X
  1130. char Lock = ' ';        /* lock status */
  1131. X
  1132. struct mounts {
  1133. X        dev_t dev;              /* st_dev */
  1134. X        char *dir;              /* directory */
  1135. X        char *fsname;           /* file system */
  1136. X    ino_t inode;        /* st_ino */
  1137. X
  1138. X#if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT)
  1139. X    u_short mode;        /* st_mode */
  1140. X#endif
  1141. X
  1142. X#if    defined(hpux) || defined(sun)
  1143. X    mode_t mode;        /* st_mode */
  1144. X#endif
  1145. X
  1146. X        struct mounts *next;    /* forward link */
  1147. X    dev_t rdev;        /* st_rdev */
  1148. X
  1149. X} *Mtab = NULL;                 /* mounted devices */
  1150. X
  1151. int Mxpid = 0;            /* maximum PID table entries */
  1152. int Mxuid = 0;            /* maximum UID table entries */
  1153. char Namech[1024];        /* name characters for printing */
  1154. int Ndev = 0;            /* number of device table entries */
  1155. X
  1156. X#if    defined(DYNIX)
  1157. struct nlist Nl[] = {
  1158. X        { "_proc" },
  1159. X#define X_PROC          0
  1160. X        {"_nproc"},
  1161. X#define X_NPROC         1
  1162. X        {"_nfs_vnodeops"},
  1163. X#define X_NFS_OPS    2
  1164. X    { "" },
  1165. X};
  1166. X#endif
  1167. X
  1168. X#if    defined(hpux)
  1169. struct nlist Nl[] = {
  1170. X
  1171. X#if    defined(hp9000s300)
  1172. X        {"_proc"},
  1173. X#define X_PROC          0
  1174. X        {"_nproc"},
  1175. X#define X_NPROC         1
  1176. X        {"_nfs_vnodeops"},
  1177. X#define X_NFS_OPS    2
  1178. X
  1179. X#if    defined(HPUX7)
  1180. X    {"_Usrptmap"},
  1181. X#define X_USRPTMAP    3
  1182. X    {"_usrpt"},
  1183. X#define X_USRPT        4
  1184. X#endif
  1185. X
  1186. X#endif
  1187. X
  1188. X#if    defined(hp9000s800)
  1189. X    {"proc"},
  1190. X#define X_PROC          0
  1191. X    {"nproc"},
  1192. X#define X_NPROC         1
  1193. X        {"nfs_vnodeops"},
  1194. X#define X_NFS_OPS    2
  1195. X
  1196. X#if    defined(HPUX7)
  1197. X    {"ubase"},
  1198. X#define X_UBASE        3
  1199. X    {"npids"},
  1200. X#define X_NPIDS        4
  1201. X#endif
  1202. X
  1203. X#endif
  1204. X
  1205. X    { "" }
  1206. X};
  1207. X#endif
  1208. X
  1209. X#if    defined(NeXT)
  1210. X
  1211. static struct nlist Nl[] = {
  1212. X        { {"_allproc"},      0, 0, 0 },
  1213. X#define X_ALLPROC                               0
  1214. X        { {"_nfs_vnodeops"}, 0, 0, 0},
  1215. X#define X_NFS_OPS                               1
  1216. X        {  {""},             0, 0, 0  },
  1217. X};
  1218. X#endif
  1219. X
  1220. X#if    defined(sun)
  1221. struct nlist Nl[] = {
  1222. X        {"_nfs_vnodeops"},
  1223. X#define X_NFS_OPS    0
  1224. X    { "_tmp_vnodeops"},
  1225. X#define X_TMP_OPS    1
  1226. X    { "" }
  1227. X};
  1228. X#endif
  1229. X
  1230. int Npid = 0;            /* -p flag count */
  1231. int Nuid = 0;            /* -u flag count */
  1232. X
  1233. X#if    defined(HPUX7) && defined(hp9000s800)
  1234. int npids;            /* number of PIDs (for uvadd()) */
  1235. struct proc *proc;        /* process table address (for uvadd()) */
  1236. X#endif
  1237. X
  1238. X#if    defined(hpux)
  1239. long Procaddr;            /* kernel process table entry address */
  1240. X#endif
  1241. X
  1242. struct dev **Sdev = NULL;    /* pointer to device table pointers, sorted
  1243. X                 * by device */
  1244. X
  1245. struct sfile {
  1246. X    char *name;        /* file name */
  1247. X    char *devnm;        /* device name (optional) */
  1248. X    dev_t dev;        /* device */
  1249. X
  1250. X#if    defined(_IBMR2)
  1251. X    chan_t ch;        /* channel (last path component, if numeric) */
  1252. X#endif
  1253. X
  1254. X    u_short mode;        /* S_IFMT mode bits from stat() */
  1255. X    int type;        /* file type: 0 = file system
  1256. X                 *          1 = regular file */
  1257. X    ino_t i;        /* inode number */
  1258. X    int f;            /* file found flag */
  1259. X    struct sfile *next;    /* link to next entry */
  1260. X
  1261. X} *Sfile = NULL;        /* chain of files to search for */
  1262. X
  1263. off_t Size;            /* file size */
  1264. int Size_def;            /* file size is defined */
  1265. int *Spid = NULL;        /* Process IDs to search for */
  1266. int *Suid = NULL;        /* User IDs to search for */
  1267. X
  1268. X#if    defined(DYNIX) || defined(hpux)
  1269. int Swap = -1;            /* swap device file descriptor */
  1270. X#endif
  1271. X
  1272. int Pid;            /* Process ID */
  1273. char *Pn;            /* program name */
  1274. X
  1275. jmp_buf Tmo_jbuf;        /* jump buffer for mount stat timeout */
  1276. X
  1277. char Type[8];            /* type for printing */
  1278. char User[USERPRTL+1];        /* User ID */
  1279. X
  1280. X#if    defined(HPUX7) && defined(hp9000s300)
  1281. struct pte *Usrptmap;        /* user page table map pointer */
  1282. struct pte *usrpt;        /* user page table pointer
  1283. X                 * (for bktomx from vmmac.h) */
  1284. X#endif
  1285. X
  1286. X#if    defined(HPUX7) && defined(hp9000s800)
  1287. struct user *ubase;        /* user area base (for uvadd()) */
  1288. X#endif
  1289. X
  1290. int Vtype;            /* vnode type (see V_* symbols) */
  1291. X
  1292. X
  1293. int compdev(), getchan(), isfile(), kread(), readinode(),
  1294. X    readlink(), readrnode(), readvnode(), statsafely();
  1295. X
  1296. char *endnm(), isglocked();
  1297. X
  1298. struct l_vfs *readvfs();
  1299. X
  1300. void printchdevname(), printfile(), printinaddr(), printiproto(),
  1301. X     printline(), printsocket(), printuid(), printvnode(), readdev(),
  1302. X     readmnt(), stkdir();
  1303. X
  1304. X#if    defined(DYNIX)
  1305. char *malloc(), *realloc();
  1306. int stattimeout();
  1307. void completevfs();
  1308. u_short ntohs();
  1309. X#endif
  1310. X
  1311. X#if    defined(hpux)
  1312. int readsnode();
  1313. off_t lseek();
  1314. void completevfs(), stattimeout();
  1315. X#endif
  1316. X
  1317. X#if    defined(_IBMR2)
  1318. int readcdrnode(), readgnode();
  1319. void stattimeout();
  1320. X#endif
  1321. X
  1322. X#if    defined(NeXT)
  1323. int readsnode();
  1324. void completevfs(), stattimeout();
  1325. X#endif
  1326. X
  1327. X#if    defined(sun)
  1328. int readfifonode(), readsnode(), readtnode();
  1329. void completevfs(), stattimeout();
  1330. X#endif
  1331. X
  1332. X/*
  1333. X * Process structure redefinitions
  1334. X */
  1335. X
  1336. X#if    defined(_IBMR2)
  1337. X#define p_pid    pi_pid
  1338. X#define p_stat    pi_stat
  1339. X#define p_uid    pi_uid
  1340. X#endif
  1341. X
  1342. X/*
  1343. X * User structure redefinitions
  1344. X */
  1345. X
  1346. X#if    defined(NeXT)
  1347. X#define u_comm    uu_comm
  1348. X#define u_cdir    uu_cdir
  1349. X#endif
  1350. X
  1351. X
  1352. X/*
  1353. X * main() - main program
  1354. X */
  1355. X
  1356. main(argc, argv)
  1357. X    int argc;
  1358. X    char *argv[];
  1359. X{
  1360. X    int c;
  1361. X    int err = 0;
  1362. X    char *fnm;
  1363. X    int fprint;
  1364. X    char *fsnm;
  1365. X    int ftype;
  1366. X    int i;
  1367. X    int llen, llenx;
  1368. X    struct mounts *mp;
  1369. X    char *path;
  1370. X    char *s;
  1371. X    struct stat sb;
  1372. X    int selflg, selpid, seluid;
  1373. X    struct sfile *sfp;
  1374. X    char syml[MAXPATHLEN];
  1375. X    char *symlp;
  1376. X    char symlx[MAXPATHLEN];
  1377. X
  1378. X#if    defined(DYNIX)
  1379. X    long kp;
  1380. X    int nf, np;
  1381. X    static struct ofile *ofp = NULL;
  1382. X    struct proc *p;
  1383. X    struct proc ps;
  1384. X    int px;
  1385. X    struct user *u;
  1386. X    struct ofile *uf;
  1387. X    unsigned ui;
  1388. X    struct user us;
  1389. X    static int xnf = 0;
  1390. X
  1391. X#if    !defined(DYNIX31)
  1392. X    struct ofile_ext ofx;
  1393. X#endif
  1394. X
  1395. X#if    defined(DYNIX31)
  1396. X    struct ofile_tab oft;
  1397. X#endif
  1398. X
  1399. X#endif
  1400. X
  1401. X#if    defined(hpux)
  1402. X
  1403. X#if    defined(HPUX7)
  1404. X    int k;
  1405. X    char us[U_SIZE];    /* must read HP-UX SWAP in DEV_BSIZE chunks */
  1406. X#endif
  1407. X
  1408. X#if    defined(HPUX8)
  1409. X    struct ofile_t *ofp;
  1410. X    struct ofile_t oft;
  1411. X    struct user us;
  1412. X#endif
  1413. X
  1414. X    int j;
  1415. X    long kp;
  1416. X    int np;
  1417. X    struct proc *p;
  1418. X    struct proc ps;
  1419. X    int px;
  1420. X    struct user *u;
  1421. X#endif
  1422. X
  1423. X#if    defined(_IBMR2)
  1424. X    int np;
  1425. X    struct procinfo *p;
  1426. X    struct user *u;
  1427. X    struct user us;
  1428. X#endif
  1429. X
  1430. X#if    defined(NeXT)
  1431. X    MALLOC_S nb;
  1432. X    int nf;
  1433. X    struct proc *np, *p, *procp, ps;
  1434. X    static MALLOC_S pnb = 0;
  1435. X        struct task t;
  1436. X        struct file **uf = NULL;
  1437. X        struct utask *u, ut;
  1438. X#endif
  1439. X
  1440. X#if    defined(sun)
  1441. X    int nf;
  1442. X    struct proc *p;
  1443. X    struct user *u;
  1444. X    struct file **uf;
  1445. X    unsigned ui;
  1446. X    static int xnf = 0;
  1447. X    static struct file **xuf = NULL;
  1448. X#endif
  1449. X
  1450. X/*
  1451. X * Save program name for messages.
  1452. X */
  1453. X    if ((Pn = strrchr(argv[0], '/')) != NULL)
  1454. X        Pn++;
  1455. X    else
  1456. X        Pn = argv[0];
  1457. X/*
  1458. X * Process arguments.
  1459. X */
  1460. X    while ((c = getopt(argc, argv, "dhlnNp:stu:U")) != EOF) {
  1461. X        switch(c) {
  1462. X
  1463. X        case 'd':
  1464. X            Fdevmsg = 1;
  1465. X            break;
  1466. X        case 'h':
  1467. X            Fhelp = 1;
  1468. X            break;
  1469. X        case 'l':
  1470. X            Futol = 0;
  1471. X            break;
  1472. X        case 'n':
  1473. X            Fnet = 1;
  1474. X            break;
  1475. X        case 'N':
  1476. X            Fnfs = 1;
  1477. X            break;
  1478. X        case 'p':
  1479. X            if (entpid(optarg))
  1480. X                err++;
  1481. X            break;
  1482. X        case 's':
  1483. X            Fsize = 0;
  1484. X            break;
  1485. X        case 't':
  1486. X            Fterse = 1;
  1487. X            break;
  1488. X        case 'u':
  1489. X            if (entuid(optarg))
  1490. X                err++;
  1491. X            break;
  1492. X        case 'U':
  1493. X            Funix = 1;
  1494. X            break;
  1495. X        case '?':
  1496. X            err++;
  1497. X            break;
  1498. X        default:
  1499. X            (void) fprintf(stderr, "%s: unknown option (%c)\n",
  1500. X                Pn, c);
  1501. X            err++;
  1502. X        }
  1503. X    }
  1504. X/*
  1505. X * Read the mount table and process any file names.
  1506. X */
  1507. X    (void) readmnt();
  1508. X    for (i = optind; i < argc; i++) {
  1509. X
  1510. X    /*
  1511. X     * Dereference a symbolic link.
  1512. X     */
  1513. X        if ((llen = readlink(argv[i], syml, sizeof(syml) - 1)) >= 0) {
  1514. X            syml[llen] = '\0';
  1515. X            if (argv[i][0] == '/' && syml[0] != '/') {
  1516. X                llenx = (strrchr(argv[i], '/') - argv[i]) + 1;
  1517. X                if ((llenx + llen + 1) > sizeof(symlx)) {
  1518. X                    (void) fprintf(stderr,
  1519. X                        "%s: sym link for %s too long\n",
  1520. X                        Pn, argv[i]);
  1521. X                    exit(1);
  1522. X                }
  1523. X                (void) strncpy(symlx, argv[i],
  1524. X                    (STRNCPY_L)llenx);
  1525. X                (void) strcpy(&symlx[llenx], syml);
  1526. X                symlp = symlx;
  1527. X                llen += llenx;
  1528. X            } else
  1529. X                symlp = syml;
  1530. X            if ((path = (char *)malloc((MALLOC_S)(llen + 1)))
  1531. X            == NULL) {
  1532. X                (void) fprintf(stderr,
  1533. X                    "%s: no space for sym link of %s\n",
  1534. X                    Pn, argv[i]);
  1535. X                exit(1);
  1536. X            }
  1537. X            (void) strcpy(path, symlp);
  1538. X        } else
  1539. X            path = argv[i];
  1540. X    /*
  1541. X     * Check for file system argument.
  1542. X     */
  1543. X        for (ftype = 1, mp = Mtab; mp; mp = mp->next) {
  1544. X            if (strcmp(mp->dir, path) == 0) {
  1545. X                ftype = 0;
  1546. X                fnm = path;
  1547. X                fsnm = mp->fsname;
  1548. X                break;
  1549. X            }
  1550. X            if (strcmp(mp->fsname, path) == 0) {
  1551. X                ftype = 0;
  1552. X                fnm = mp->dir;
  1553. X                fsnm = path;
  1554. X                break;
  1555. X            }
  1556. X        }
  1557. X        if (ftype) {
  1558. X            fnm = path;
  1559. X            fsnm = NULL;
  1560. X        } else {
  1561. X            sb.st_dev = mp->dev;
  1562. X            sb.st_ino = mp->inode;
  1563. X            sb.st_mode = mp->mode;
  1564. X            sb.st_rdev = mp->rdev;
  1565. X        }
  1566. X    /*
  1567. X     * Stat the argument to obtain its mode and device.
  1568. X     */
  1569. X
  1570. X        if (ftype && statsafely(fnm, &sb, STATTMO) != 0) {
  1571. X            (void) fprintf(stderr, "%s: status error on %s: %s\n",
  1572. X                Pn, fnm, sys_errlist[errno]);
  1573. X            err++;
  1574. X            continue;
  1575. X        }
  1576. X    /*
  1577. X     * Allocate an sfile structure and fill in the type, inode,
  1578. X     * find-flag and linkages.
  1579. X     */
  1580. X        if ((sfp = (struct sfile *)malloc(sizeof(struct sfile)))
  1581. X        == NULL) {
  1582. X            (void) fprintf(stderr, "%s: no space for files\n", Pn);
  1583. X            exit(1);
  1584. X        }
  1585. X        sfp->next = Sfile;
  1586. X        Sfile = sfp;
  1587. X        sfp->type = ftype;
  1588. X        sfp->i = sb.st_ino;
  1589. X        sfp->f = 0;
  1590. X    /*
  1591. X     * Store the file name and file system name pointers in the sfile
  1592. X     * structure, allocating space as necessary.
  1593. X     */
  1594. X        if (fnm == NULL || fnm == path)
  1595. X            sfp->name = fnm;
  1596. X        else {
  1597. X            if ((sfp->name = (char *)malloc((MALLOC_S)(strlen(fnm)+1)))
  1598. X            == NULL) {
  1599. X            (void) fprintf(stderr,
  1600. X                "%s: no space for file name %s\n", Pn, fnm);
  1601. X            exit(1);
  1602. X            }
  1603. X            (void) strcpy(sfp->name, fnm);
  1604. X        }
  1605. X        if (fsnm == NULL || fsnm == path)
  1606. X            sfp->devnm = fsnm;
  1607. X        else {
  1608. X            if ((sfp->devnm=(char *)malloc((MALLOC_S)(strlen(fsnm)+1)))
  1609. X            == NULL) {
  1610. X            (void) fprintf(stderr,
  1611. X                "%s: no space for file system name %s\n", Pn, fsnm);
  1612. X            exit(1);
  1613. X            }
  1614. X            (void) strcpy(sfp->devnm, fsnm);
  1615. X        }
  1616. X    /*
  1617. X     * Save the stat() buffer mode value in the sfile structure.
  1618. X     * Use st_rdev if the mode value is S_IFBLK or S_IFCHR; otherwise
  1619. X     * use st_dev.
  1620. X     */
  1621. X        sfp->mode = sb.st_mode & S_IFMT;
  1622. X        if (sfp->mode == S_IFBLK ||  sfp->mode == S_IFCHR)
  1623. X            sfp->dev = sb.st_rdev;
  1624. X        else
  1625. X            sfp->dev = sb.st_dev;
  1626. X
  1627. X#if    defined(_IBMR2)
  1628. X    /*
  1629. X     * Save a (possible) AIX multiplexed channel number.
  1630. X     */
  1631. X        sfp->ch = getchan(path);
  1632. X#endif
  1633. X
  1634. X    }
  1635. X/*
  1636. X * List usage if error or if requested.
  1637. X */
  1638. X    if (err || Fhelp) {
  1639. X        (void) fprintf(stderr,
  1640. X        "%s %s usage: [-d] [-h] [-l] [-n] [-N] [-p l] [-s] [-t]",
  1641. X        Pn, Version);
  1642. X        (void) fprintf(stderr,
  1643. X        " [-u l] [-U] [names]\n");
  1644. X        (void) fprintf(stderr,
  1645. X        "\t-d     issue /dev subdirectory error messages\n");
  1646. X        (void) fprintf(stderr,
  1647. X        "\t-h     list help\n");
  1648. X        (void) fprintf(stderr,
  1649. X        "\t-l     do not convert UID's to login names\n");
  1650. X        (void) fprintf(stderr,
  1651. X        "\t-n     list Internet network files\n");
  1652. X        (void) fprintf(stderr,
  1653. X        "\t-N     list NFS files\n");
  1654. X        (void) fprintf(stderr,
  1655. X        "\t-p l   list files for comma-separated Process ID list l\n");
  1656. X        (void) fprintf(stderr,
  1657. X         "\t-s     do not display file size\n");
  1658. X        (void) fprintf(stderr,
  1659. X        "\t-t     terse output -- Process ID numbers and no header\n");
  1660. X        (void) fprintf(stderr,
  1661. X        "\t-u l   list files for comma-separated user list l ");
  1662. X        (void) fprintf(stderr,
  1663. X        "(names or UIDs)\n");
  1664. X        (void) fprintf(stderr,
  1665. X        "\t-U     list Unix domain sockets\n");
  1666. X        (void) fprintf(stderr,
  1667. X        "\tnames  path names of file systems, mount points, devices");
  1668. X        (void) fprintf(stderr,
  1669. X        " and\n\t       files to locate\n");
  1670. X        if (err)
  1671. X        exit(1);
  1672. X        exit(0);
  1673. X    }
  1674. X/*
  1675. X * Open kernel memory accesses.
  1676. X *
  1677. X * Read and build device and mount tables.
  1678. X */
  1679. X    if ((Kmem = open("/dev/kmem", O_RDONLY, 0)) < 0) {
  1680. X        (void) fprintf(stderr, "%s: can't open /dev/kmem: %s\n",
  1681. X            Pn, sys_errlist[errno]);
  1682. X        exit(1);
  1683. X    }
  1684. X
  1685. X#if    defined(HPUX7)
  1686. X    if ((Mem = open("/dev/mem", O_RDONLY, 0)) < 0) {
  1687. X        (void) fprintf(stderr, "%s: can't open /dev/mem: %s",
  1688. X            Pn, sys_errlist[errno]);
  1689. X        exit(1);
  1690. X    }
  1691. X#endif
  1692. X
  1693. X#if    defined(DYNIX) || defined(HPUX7)
  1694. X    if ((Swap = open(SWAP, O_RDONLY, 0)) < 0) {
  1695. X        (void) fprintf(stderr, "%s: /dev/drum: %s\n",
  1696. X            Pn, sys_errlist[errno]);
  1697. X        exit(1);
  1698. X    }
  1699. X#endif
  1700. X
  1701. X#if    defined(NeXT)
  1702. X        if (nlist(VMUNIX, Nl) < 0) {
  1703. X                (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
  1704. X                exit(1);
  1705. X        }
  1706. X        if (Nl[X_ALLPROC].n_value == 0l) {
  1707. X                (void) fprintf(stderr, "%s: no address for %s\n",
  1708. X                        Pn, Nl[X_ALLPROC].n_un.n_name);
  1709. X                exit(1);
  1710. X        }
  1711. X        if (kread((off_t)Nl[X_ALLPROC].n_value, (char *)&procp, sizeof(procp))){
  1712. X                (void) fprintf(stderr,
  1713. X                        "%s: can't read nl[X_ALLPROC].n_un.n_name: %s\n",
  1714. X                        Pn, sys_errlist[errno]);
  1715. X                exit(1);
  1716. X        }
  1717. X#endif
  1718. X
  1719. X#if    defined(sun)
  1720. X    if ((Kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == 0) {
  1721. X        (void) sprintf("%s: kvm_open: %s", Pn, sys_errlist[errno]);
  1722. X        exit(1);
  1723. X    }
  1724. X        if (nlist(N_UNIX, Nl) < 0) {
  1725. X                (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
  1726. X                exit(1);
  1727. X    }
  1728. X        if (Nl[X_NFS_OPS].n_value == 0l) {
  1729. X                (void) fprintf(stderr, "%s: no address for %s\n",
  1730. X                        Pn, Nl[X_NFS_OPS].n_name);
  1731. X                exit(1);
  1732. X        }
  1733. X#endif
  1734. X
  1735. X    (void) readdev();
  1736. X/*
  1737. X * Read the processs table.
  1738. X */
  1739. X
  1740. X#if    defined(DYNIX) || defined(hpux)
  1741. X    if (nlist(N_UNIX, Nl) < 0) {
  1742. X                (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
  1743. X                exit(1);
  1744. X    }
  1745. X    if (Nl[X_PROC].n_value == NULL
  1746. X    ||  kread((off_t)Nl[X_PROC].n_value, (char *)&kp, sizeof(kp))
  1747. X    ||  Nl[X_NPROC].n_value == NULL
  1748. X    ||  kread((off_t)Nl[X_NPROC].n_value, (char *)&np, sizeof(np))
  1749. X    ||  kp == NULL || np == 0) {
  1750. X        (void) fprintf(stderr, "%s: can't read proc table info\n",
  1751. X            Pn);
  1752. X        exit(1);
  1753. X    }
  1754. X#endif
  1755. X
  1756. X#if    defined(HPUX7) && defined(hp9000s300)
  1757. X    if ((Usrptmap = (struct pte *)Nl[X_USRPTMAP].n_value) == NULL) {
  1758. X        (void) fprintf(stderr, "%s: can't get kernel's Usrptmap\n", Pn);
  1759. X        exit(1);
  1760. X    }
  1761. X    if ((usrpt = (struct pte *)Nl[X_USRPT].n_value) == NULL) {
  1762. X        (void) fprintf(stderr, "%s: can't get kernel's usrpt\n", Pn);
  1763. X        exit(1);
  1764. X    }
  1765. X#endif
  1766. X
  1767. X#if    defined(HPUX7) && defined(hp9000s800)
  1768. X    proc = (struct proc *)kp;
  1769. X    if ((ubase = (struct user *)Nl[X_UBASE].n_value) == NULL) {
  1770. X        (void) fprintf(stderr, "%s: can't get kernel's ubase\n", Pn);
  1771. X        exit(1);
  1772. X    }
  1773. X    if (Nl[X_NPIDS].n_value == NULL
  1774. X    ||  kread((off_t)Nl[X_NPIDS].n_value, (char *)&npids, sizeof(npids))) {
  1775. X        (void) fprintf(stderr, "%s: can't get kernel's npids\n", Pn);
  1776. X        exit(1);
  1777. X    }
  1778. X#endif
  1779. X
  1780. X#if    defined(_IBMR2)
  1781. X    if ((p = (struct procinfo *)malloc((size_t)PROCSIZE)) == NULL) {
  1782. X        (void) fprintf(stderr,
  1783. X            "%s: can't allocate space for 1 procinfo\n", Pn);
  1784. X        exit(1);
  1785. X    }
  1786. X    np = 0;
  1787. X    while (((np = getproc(p, np, PROCSIZE)) == -1) && errno == ENOSPC) {
  1788. X        np = p->p_pid + 10;
  1789. X        if ((p = (struct procinfo *)realloc((MALLOC_P *)p,
  1790. X            (size_t) (np * PROCSIZE))) == NULL) {
  1791. X            (void) fprintf(stderr,
  1792. X                "%s: no space for %ld procinfo's\n", Pn, np);
  1793. X            exit(1);
  1794. X        }
  1795. X    }
  1796. X#endif
  1797. X
  1798. X#if    defined(sun)
  1799. X    (void) kvm_setproc(Kd);
  1800. X#endif
  1801. X
  1802. X/*
  1803. X * Loop through the process table entries.
  1804. X */
  1805. X    selflg = (Fnet || Fnfs || Funix || Npid || Nuid || Sfile) ? 0 : 1;
  1806. X    selpid = (Fnet || Fnfs || Funix || Nuid || Sfile) ? 0 : 1;
  1807. X    seluid = (Fnet || Fnfs || Funix || Sfile) ? 0 : 1;
  1808. X
  1809. X#if    defined(DYNIX)
  1810. X    for (p = &ps, px = 0, u = &us; px < np; px++)
  1811. X#endif
  1812. X
  1813. X#if    defined(HPUX7)
  1814. X    for (p = &ps, px = 0, u = (struct user *)us; px < np; px++)
  1815. X#endif
  1816. X
  1817. X#if    defined(HPUX8)
  1818. X    for (p = &ps, px = 0, u = &us; px < np; px++)
  1819. X#endif
  1820. X
  1821. X#if    defined(_IBMR2)
  1822. X    for (; np; np--, p++)
  1823. X#endif
  1824. X
  1825. X#if    defined(NeXT)
  1826. X    for (np = procp, p = &ps; np; np = ps.p_nxt)
  1827. X#endif
  1828. X
  1829. X#if    defined(sun)
  1830. X    while ((p = kvm_nextproc(Kd)) != NULL)
  1831. X#endif
  1832. X
  1833. X    {
  1834. X
  1835. X#if    defined(DYNIX)
  1836. X        if (kread((off_t)(kp + (long)(px * sizeof(struct proc))),
  1837. X            (char *)&ps, sizeof(ps)))
  1838. X            continue;
  1839. X#endif
  1840. X
  1841. X#if    defined(hpux)
  1842. X        Procaddr = kp + (long)(px * sizeof(struct proc));
  1843. X        if (kread((off_t)Procaddr, (char *)&ps, sizeof(ps)))
  1844. X            continue;
  1845. X#endif
  1846. X
  1847. X#if    defined(NeXT)
  1848. X                if (kread((off_t)np, (char *)&ps, sizeof(ps))) {
  1849. X                        (void) fprintf(stderr,
  1850. X                                "%s: can't read proc struct at %#x\n",
  1851. X                                Pn, np);
  1852. X                        exit(1);
  1853. X                }
  1854. X#endif
  1855. X
  1856. X        if (p->p_stat == 0 || p->p_stat == SZOMB)
  1857. X            continue;
  1858. X        fprint = selflg;
  1859. X        for (i = 0; fprint == 0 && i < Npid; i++) {
  1860. X            if (Spid[i] == p->p_pid)
  1861. X                fprint = 1;
  1862. X        }
  1863. X        if ( ! fprint && selpid)
  1864. X            continue;
  1865. X
  1866. X#if    defined(NeXT)
  1867. X        /*
  1868. X         * Read the task associated with the process, and the user
  1869. X         * area assocated with the task.
  1870. X         */
  1871. X                if (kread((off_t) p->task, &t, sizeof(t)))
  1872. X                        continue;
  1873. X                if ((struct proc *)t.proc != np)
  1874. X                        continue;
  1875. X                if (kread((off_t) t.u_address, &ut, sizeof(ut)))
  1876. X                        continue;
  1877. X                if ((struct proc *)ut.uu_procp != np)
  1878. X                        continue;
  1879. X        u = &ut;
  1880. X#endif
  1881. X
  1882. X/*
  1883. X * Check for processes owned by specified user(s).
  1884. X */
  1885. X        for (i = 0; fprint == 0 && i < Nuid; i++) {
  1886. X            if (Suid[i] == p->p_uid)
  1887. X                fprint = 1;
  1888. X        }
  1889. X        if ( ! fprint && seluid)
  1890. X            continue;
  1891. X
  1892. X#if    defined(DYNIX) || defined(hpux) || defined(_IBMR2) || defined(sun)
  1893. X    /*
  1894. X     * Get the user area associated with the process.
  1895. X     */
  1896. X#endif
  1897. X
  1898. X#if    defined(DYNIX)
  1899. X        if (getu(p, &us))
  1900. X            continue;
  1901. X#endif
  1902. X
  1903. X#if    defined(hpux)
  1904. X        if (getu(p, u))
  1905. X            continue;
  1906. X#endif
  1907. X
  1908. X#if    defined(_IBMR2)
  1909. X        u = &us;
  1910. X        if (getuser(p, PROCSIZE, u, U_SIZE) != 0)
  1911. X            continue;
  1912. X#endif
  1913. X
  1914. X#if    defined(sun)
  1915. X        if ((u = kvm_getu(Kd, p)) == NULL)
  1916. X            continue;
  1917. X#endif
  1918. X
  1919. X    /*
  1920. X     * Print information on the current directory.
  1921. X     */
  1922. X
  1923. X#if    defined(DYNIX) || defined(HPUX7) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  1924. X        if (u->u_cdir) {
  1925. X#endif
  1926. X
  1927. X#if    defined(HPUX8)
  1928. X        if (p->p_cdir) {
  1929. X#endif
  1930. X
  1931. X            Command = u->u_comm;
  1932. X            Fdev = 0;
  1933. X            Devch[0] = Iproto[0] = Type[0] = '\0';
  1934. X        /*
  1935. X         * The following line should be:
  1936. X         *
  1937. X         *    (void) strcpy(Fd, " cwd");
  1938. X         *
  1939. X         * However, the 3.1.3 xlc compiler produces incorrect code
  1940. X         * for it when optimizing (-O).  The 3.1.5 xlc compiles the
  1941. X         * strcpy() correctly.
  1942. X         */
  1943. X            (void) sprintf(Fd, "%4s", "cwd");
  1944. X            Fprint = fprint;
  1945. X            Inode = -1l;
  1946. X            Lock = ' ';
  1947. X            Namech[0] = '\0';
  1948. X            Pid = p->p_pid;
  1949. X            Size_def = 0;
  1950. X            Vtype = V_REG;
  1951. X            (void) printuid(p->p_uid);
  1952. X
  1953. X#if    defined(DYNIX) || defined(HPUX7) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  1954. X            printvnode((caddr_t)u->u_cdir);
  1955. X#endif
  1956. X
  1957. X#if    defined(HPUX8)
  1958. X            printvnode((caddr_t)p->p_cdir);
  1959. X#endif
  1960. X        }
  1961. X    /*
  1962. X     * Loop through user's files.
  1963. X     */
  1964. X
  1965. X#if    defined(DYNIX)
  1966. X
  1967. X#if    !defined(DYNIX31)
  1968. X    /*
  1969. X     * Under DYNIX, the file pointers may be located in the user
  1970. X     * structure or in an extension to it.  Determine which is the
  1971. X     * case and read the pointers.
  1972. X     */
  1973. X
  1974. X    if (u->u_ofile_ext) {
  1975. X        if (kread((off_t)u->u_ofile_ext, (char *)&ofx, sizeof(ofx)))
  1976. X            nf = 0;
  1977. X        else {
  1978. X            nf = ofx.oe_nofile;
  1979. X            ui = (unsigned)(ofx.oe_nofile * sizeof(struct ofile));
  1980. X            if (ofp == NULL) {
  1981. X                xnf = nf;
  1982. X                if ((ofp = (struct ofile *)malloc(ui))
  1983. X                == NULL) {
  1984. X                    (void) fprintf(stderr,
  1985. X                        "%s: no malloc ofile space\n",
  1986. X                        Pn);
  1987. X                    exit(1);
  1988. X                }
  1989. X            } else if (nf > xnf) {
  1990. X                xnf = nf;
  1991. X                if ((ofp = (struct ofile *)realloc(
  1992. X                       (MALLOC_P *)ofp, ui))
  1993. X                == NULL) {
  1994. X                    (void) fprintf(stderr,
  1995. X                        "%s: no realloc ofile space\n",
  1996. X                        Pn);
  1997. X                    exit(1);
  1998. X                }
  1999. X            }
  2000. X            if (kread((off_t)ofx.oe_ofile, (char *)ofp, (int)ui))
  2001. X                nf = 0;
  2002. X            else {
  2003. X                nf = ofx.oe_nofile;
  2004. X                uf = ofp;
  2005. X            }
  2006. X        }
  2007. X    } else {
  2008. X        nf = NOFILE;
  2009. X        uf = u->u_lofile;
  2010. X    }
  2011. X#endif
  2012. X
  2013. X#if    defined(DYNIX31)
  2014. X    /*
  2015. X     * Under DYNIX 3.1, the file pointers should be located in an extension
  2016. X     * to the user structure.  Determine if is the case and read the
  2017. X     * pointers.
  2018. X     */
  2019. X
  2020. X    if (u->u_ofile_tab) {
  2021. X        if (kread((off_t)u->u_ofile_tab, (char *)&oft, sizeof(oft)))
  2022. X            nf = 0;
  2023. X        else {
  2024. X            nf = oft.oft_nofile;
  2025. X            ui = (unsigned)(oft.oft_nofile * sizeof(struct ofile));
  2026. X            if (ofp == NULL) {
  2027. X                xnf = nf;
  2028. X                if ((ofp = (struct ofile *)malloc(ui))
  2029. X                == NULL) {
  2030. X                    (void) fprintf(stderr,
  2031. X                        "%s: no malloc ofile space\n",
  2032. X                        Pn);
  2033. X                    exit(1);
  2034. X                }
  2035. X            } else if (nf > xnf) {
  2036. X                xnf = nf;
  2037. X                if ((ofp = (struct ofile *)realloc(
  2038. X                       (MALLOC_P *)ofp, ui))
  2039. X                == NULL) {
  2040. X                    (void) fprintf(stderr,
  2041. X                        "%s: no realloc ofile space\n",
  2042. X                        Pn);
  2043. X                    exit(1);
  2044. X                }
  2045. X            }
  2046. X            if (kread((off_t)oft.oft_ofile, (char *)ofp, (int)ui))
  2047. X                nf = 0;
  2048. X            else {
  2049. X                nf = oft.oft_nofile;
  2050. X                uf = ofp;
  2051. X            }
  2052. X        }
  2053. X    } else {
  2054. X        nf = NOFILE;
  2055. X        uf = u->u_lofileXXX;
  2056. X    }
  2057. X#endif
  2058. X
  2059. X#endif
  2060. X
  2061. X#if    defined(NeXT)
  2062. X    /*
  2063. X     * NeXTStep 2.0 and 2.1 file pointers come from a structure whose
  2064. X     * pointer is in the user area.
  2065. X     */
  2066. X        nf = ut.uu_ofile_cnt;
  2067. X                nb = (MALLOC_S) (sizeof(struct file) * nf);
  2068. X        if (uf == NULL) {
  2069. X            if ((uf = (struct file **)malloc(nb)) == NULL) {
  2070. X                (void) fprintf(stderr,
  2071. X                    "%s: no file table space, process %d\n",
  2072. X                    Pn, p->p_pid);
  2073. X                exit(1);
  2074. X            }
  2075. X            pnb = nb;
  2076. X        } else if (nb > pnb) {
  2077. X            if ((uf = (struct file **)realloc((MALLOC_P *)uf, nb))
  2078. X            == NULL) {
  2079. X                (void) fprintf(stderr,
  2080. X                    "%s: realloc file[]\n", Pn);
  2081. X                exit(1);
  2082. X            }
  2083. X            pnb = nb;
  2084. X        }
  2085. X                if (kread((off_t)ut.uu_ofile, (char *)uf, nb))
  2086. X                        continue;
  2087. X#endif
  2088. X    
  2089. X#if    defined(sun)
  2090. X    /*
  2091. X     * Under SunOS 4.1.1, the file pointers may be located in the
  2092. X     * user structure or in a separately allocated area.  Determine
  2093. X     * which is the case and read the pointers.
  2094. X     */
  2095. X        if ((caddr_t)u->u_ofile
  2096. X        == ((caddr_t)&u->u_ofile_arr[0] - (caddr_t)&u
  2097. X        + (caddr_t)p->p_uarea)) {
  2098. X            nf = NOFILE_IN_U;
  2099. X            uf = &u->u_ofile_arr[0];
  2100. X        } else {
  2101. X            nf = u->u_lastfile + 1;
  2102. X            ui = nf * sizeof(struct file);
  2103. X            if (xuf == NULL) {
  2104. X                xnf = nf;
  2105. X                if ((xuf = (struct file **)malloc(ui))
  2106. X                == NULL) {
  2107. X                    (void) fprintf(stderr,
  2108. X                        "%s: malloc file[]\n", Pn);
  2109. X                    exit(1);
  2110. X                }
  2111. X            } else if (nf > xnf) {
  2112. X                xnf = nf;
  2113. X                if ((xuf = (struct file **)realloc(
  2114. X                       (MALLOC_P *)xuf, ui))
  2115. X                == NULL) {
  2116. X                    (void) fprintf(stderr,
  2117. X                        "%s: realloc file[]\n", Pn);
  2118. X                    exit(1);
  2119. X                }
  2120. X            }
  2121. X            if (kread((off_t)u->u_ofile, (char *)xuf, (int)ui))
  2122. X                nf = 0;
  2123. X            uf = xuf;
  2124. X        }
  2125. X#endif
  2126. X
  2127. X#if    defined(DYNIX)
  2128. X        for (i = 0; i < nf; i++) {
  2129. X            if (uf[i].of_file)
  2130. X#endif
  2131. X
  2132. X#if    defined(HPUX7)
  2133. X        for (i = j = k = 0;; i++) {
  2134. X            if (j >= SFDCHUNK) {
  2135. X
  2136. X            /*
  2137. X             * Get next HP-UX file pointer "chunk".
  2138. X             */
  2139. X                while (++k < NFDCHUNKS && u->u_ofilep[k] == NULL)
  2140. X                ;
  2141. X                if (k >= NFDCHUNKS)
  2142. X                break;
  2143. X                if (kread((off_t)u->u_ofilep[k],
  2144. X                      (char *)&u->u_ofile,
  2145. X                      sizeof(struct ofile_t)))
  2146. X                break;
  2147. X                j = 0;
  2148. X            }
  2149. X            j++;
  2150. X            if (u->u_ofile.ofile[j - 1])
  2151. X#endif
  2152. X
  2153. X#if    defined(HPUX8)
  2154. X        for (i = 0, j = SFDCHUNK;; i++) {
  2155. X            if (j >= SFDCHUNK) {
  2156. X                if (kread((off_t)p->p_ofilep, (char *)&ofp,
  2157. X                       sizeof(ofp)))
  2158. X                {
  2159. X                (void) fprintf(stderr,
  2160. X                    "%s: can't read ofilep from %#x\n",
  2161. X                    Pn, ofp);
  2162. X                exit(1);
  2163. X                }
  2164. X                if (ofp == NULL)
  2165. X                break;
  2166. X                if (kread((off_t)ofp, (char *)&oft, sizeof(oft))) {
  2167. X                (void) fprintf(stderr,
  2168. X                    "%s: can't read ofile_t from %#x\n",
  2169. X                    Pn, ofp);
  2170. X                exit(1);
  2171. X                }
  2172. X                j = 0;
  2173. X                p->p_ofilep++;
  2174. X            }
  2175. X            j++;
  2176. X            if (oft.ofile[j - 1])
  2177. X#endif
  2178. X
  2179. X#if    defined(_IBMR2)
  2180. X        for (i = 0; i < u->u_maxofile; i++) {
  2181. X            if (u->u_ufd[i].fp)
  2182. X#endif
  2183. X
  2184. X#if    defined(NeXT) || defined(sun)
  2185. X        for (i = 0; i < nf; i++) {
  2186. X            if (uf[i])
  2187. X#endif
  2188. X            {
  2189. X
  2190. X                                Command = u->u_comm;
  2191. X                                Fdev = 0;
  2192. X                Fprint = fprint;
  2193. X                                Devch[0] = Iproto[0] = Type[0] = '\0';
  2194. X                                (void) sprintf(Fd, "%4d", i);
  2195. X                                Inode = -1l;
  2196. X                                Lock = ' ';
  2197. X                                Namech[0] = '\0';
  2198. X                                Pid = p->p_pid;
  2199. X                Size_def = 0;
  2200. X                Vtype = V_REG;
  2201. X                (void) printuid(p->p_uid);
  2202. X
  2203. X#if    defined(DYNIX)
  2204. X                printfile(uf[i].of_file);
  2205. X#endif
  2206. X
  2207. X#if    defined(HPUX7)
  2208. X                printfile(u->u_ofile.ofile[j - 1]);
  2209. X#endif
  2210. X
  2211. X#if    defined(HPUX8)
  2212. X                printfile(oft.ofile[j - 1]);
  2213. X#endif
  2214. X
  2215. X#if    defined(_IBMR2)
  2216. X                                printfile(u->u_ufd[i].fp);
  2217. X#endif
  2218. X
  2219. X#if    defined(NeXT)
  2220. X                printfile(uf[i]);
  2221. X#endif
  2222. X
  2223. X#if    defined(sun)
  2224. X                                printfile(uf[i]);
  2225. X#endif
  2226. X            }
  2227. X        }
  2228. X    }
  2229. X    for (sfp = Sfile; sfp; sfp = sfp->next) {
  2230. X        if (sfp->f == 0)
  2231. X            exit(1);
  2232. X    }
  2233. X
  2234. X#if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT)
  2235. X    exit(0);
  2236. X#endif
  2237. X
  2238. X#if    defined(hpux) || defined(sun)
  2239. X    return(0);
  2240. X#endif
  2241. X
  2242. X}
  2243. X
  2244. X
  2245. X/*
  2246. X * compdev() - compare device numbers
  2247. X */
  2248. X
  2249. compdev(p1, p2)
  2250. X    struct dev **p1;
  2251. X    struct dev **p2;
  2252. X{
  2253. X    if ((long)((*p1)->rdev) < (long)((*p2)->rdev))
  2254. X        return(-1);
  2255. X    if ((long)((*p1)->rdev) > (long)((*p2)->rdev))
  2256. X        return(1);
  2257. X    return(0);
  2258. X}
  2259. X
  2260. X
  2261. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2262. X/*
  2263. X * completevfs() - complete local vfs structure
  2264. X */
  2265. X
  2266. void
  2267. completevfs(vfs, dev)
  2268. X    struct l_vfs *vfs;        /* local vfs structure pointer */
  2269. X    dev_t dev;            /* inode/rnode device */
  2270. X{
  2271. X    struct mounts *mp;
  2272. X
  2273. X    for (mp = Mtab; mp; mp = mp->next) {
  2274. X        if (mp->dev == dev) {
  2275. X
  2276. X#if    defined(DYNIX) || defined(hpux)
  2277. X            vfs->dev = mp->dev;
  2278. X#endif
  2279. X
  2280. X            vfs->dir = mp->dir;
  2281. X            vfs->fsname = mp->fsname;
  2282. X            return;
  2283. X        }
  2284. X    }
  2285. X}
  2286. X#endif
  2287. X
  2288. X
  2289. X/*
  2290. X * endnm() - locate end of Namech
  2291. X */
  2292. X
  2293. char *
  2294. endnm()
  2295. X{
  2296. X    char *s;
  2297. X
  2298. X    for (s = Namech; *s; s++)
  2299. X        ;
  2300. X    return(s);
  2301. X}
  2302. X
  2303. X
  2304. X/*
  2305. X * entpid() - enter Process IDentifier for searching
  2306. X */
  2307. X
  2308. entpid(p)
  2309. X    char *p;            /* PID string pointer */
  2310. X{
  2311. X    int i, pid;
  2312. X    char *s;
  2313. X
  2314. X    for (s = p; *s;) {
  2315. X    /*
  2316. X     * Assemble Process IDentifier.
  2317. X     */
  2318. X        for (pid = 0; *s && *s != ','; *s++) {
  2319. X            if ( ! isascii(*s) || ! isdigit(*s)) {
  2320. X                (void) fprintf(stderr,
  2321. X                    "%s: illegal PID specification: %s\n",
  2322. X                    Pn, p);
  2323. X                return(1);
  2324. X            }
  2325. X            pid = (pid * 10) + *s - '0';
  2326. X        }
  2327. X        if (*s)
  2328. X            s++;
  2329. X    /*
  2330. X     * Avoid entering duplicates.
  2331. X     */
  2332. X        for (i = 0; i < Npid; i++) {
  2333. X            if (pid == Spid[i])
  2334. X                break;
  2335. X        }
  2336. X        if (i < Npid)
  2337. X            continue;
  2338. X    /*
  2339. X     * Allocate PID table space.
  2340. X     */
  2341. X        if (Npid >= Mxpid) {
  2342. X            Mxpid += PIDINCR;
  2343. X            if (Spid == NULL)
  2344. X                Spid = (int *)malloc((MALLOC_S)
  2345. X                    (sizeof(int *) * Mxpid));
  2346. X            else
  2347. X                Spid = (int *)realloc((MALLOC_P *)Spid,
  2348. X                    (MALLOC_S)(sizeof(int *) * Mxpid));
  2349. X            if (Spid == NULL) {
  2350. X                (void) fprintf(stderr, "%s: no space for PIDs",
  2351. X                    Pn);
  2352. X                exit(1);
  2353. X            }
  2354. X        }
  2355. X        Spid[Npid++] = pid;
  2356. X    }
  2357. X    return(0);
  2358. X}
  2359. X
  2360. X
  2361. X/*
  2362. X * entuid() - enter User Identifier for searching
  2363. X */
  2364. X
  2365. entuid(u)
  2366. X    char *u;            /* User IDentifier string pointer */
  2367. X{
  2368. X    int err, i, n;
  2369. X    struct passwd *pw;
  2370. X    char *s;
  2371. X    char uid[LOGINML];
  2372. X
  2373. X    for (err = 0, s = u; *s;) {
  2374. X    /*
  2375. X     * Assemble next User IDentifier.
  2376. X     */
  2377. X        for (i = n = 0; *s && *s != ','; i++, s++) {
  2378. X            if (i >= LOGINML-1) {
  2379. X                (void) fprintf(stderr,
  2380. X                    "%s: illegal UID in %s\n", Pn, u);
  2381. X                return(1);
  2382. X            }
  2383. X            uid[i] = *s;
  2384. X            if (n < 0)
  2385. X                continue;
  2386. X            if (isascii(*s) && isdigit(*s))
  2387. X                n = (n * 10) + *s - '0';
  2388. X            else
  2389. X                n = -1;
  2390. X        }
  2391. X        if (*s)
  2392. X            s++;
  2393. X        if (n < 0) {
  2394. X               uid[i] = '\0';
  2395. X               if ((pw = getpwnam(uid)) == NULL) {
  2396. X                (void) fprintf(stderr,
  2397. X                    "%s: can't get UID for %s\n",
  2398. X                    Pn, uid);
  2399. X                err++;
  2400. X                continue;
  2401. X            } else
  2402. X                n = pw->pw_uid;
  2403. X        }
  2404. X    /*
  2405. X     * Avoid entering duplicates.
  2406. X     */
  2407. X        for (i = 0; i < Nuid; i++) {
  2408. X            if (n == Suid[i])
  2409. X                break;
  2410. X        }
  2411. X        if (i < Nuid)
  2412. X            continue;
  2413. X    /*
  2414. X     * Allocate space for User IDentifier.
  2415. X     */
  2416. X        if (Nuid >= Mxuid) {
  2417. X            Mxuid += UIDINCR;
  2418. X            if (Suid == NULL)
  2419. X                Suid = (int *)malloc((MALLOC_S)
  2420. X                    (sizeof(int *) * Mxuid));
  2421. X            else
  2422. X                Suid = (int *)realloc((MALLOC_P *)Suid,
  2423. X                    (MALLOC_S)(sizeof(int *) * Mxuid));
  2424. X            if (Suid == NULL) {
  2425. X                (void) fprintf(stderr, "%s: no space for UIDs",
  2426. X                    Pn);
  2427. X                exit(1);
  2428. X            }
  2429. X        }
  2430. X        Suid[Nuid++] = n;
  2431. X    }
  2432. X    return(err);
  2433. X}
  2434. X
  2435. X
  2436. X#if    defined(_IBMR2)
  2437. X/*
  2438. X * getchan() - get channel from file path name
  2439. X */
  2440. X
  2441. int
  2442. getchan(p)
  2443. X    char *p;            /* file path name */
  2444. X{
  2445. X    int ch;
  2446. X    char *s;
  2447. X
  2448. X    if ((s = strrchr(p, '/')) == NULL) 
  2449. X        return(-1);
  2450. X    if (*(++s) == '\0')
  2451. X        return(-1);
  2452. X    for (ch = 0; *s; s++) {
  2453. X        if ( ! isascii(*s) || ! isdigit(*s))
  2454. X            return(-1);
  2455. X        ch = (ch * 10) + *s - '0';
  2456. X    }
  2457. X    return(ch);
  2458. X}
  2459. X#endif
  2460. X
  2461. X
  2462. X#if    defined(DYNIX)
  2463. X/*
  2464. X * getu() - get DYNIX user area
  2465. X */
  2466. X
  2467. getu(p, u)
  2468. X    struct proc *p;            /* process area pointer */
  2469. X    struct user *u;            /* user area destination */
  2470. X{
  2471. X    off_t sp;
  2472. X
  2473. X    if ((p->p_flag & SLOAD) == 0) {
  2474. X        sp = (off_t) dtob(p->p_swaddr);
  2475. X        if (lseek(Swap, sp, L_SET) != sp
  2476. X        ||  read(Swap, (char*)u, U_SIZE) != U_SIZE)
  2477. X            return(1);
  2478. X    } else {
  2479. X        if (kread((off_t)p->p_uarea, (char *)u, U_SIZE))
  2480. X            return(1);
  2481. X    }
  2482. X    return(0);
  2483. X}
  2484. X#endif
  2485. X
  2486. X
  2487. X#if    defined(hpux)
  2488. X/*
  2489. X * getu() - get HP-UX user area
  2490. X */
  2491. X
  2492. getu(p, u)
  2493. X    struct proc *p;            /* process area pointer */
  2494. X
  2495. X#if    defined(HPUX7)
  2496. X    char *u;            /* user area destination */
  2497. X#endif
  2498. X
  2499. X#if    defined(HPUX8)
  2500. X    struct user *u;            /* user area destination */
  2501. X#endif
  2502. X
  2503. X{
  2504. X
  2505. X#if    defined(HPUX7)
  2506. X    long sw;
  2507. X
  2508. X#if    defined(hp9000s300)
  2509. X    struct pte pte1, pte2;
  2510. X    off_t pte_off, pte_addr;
  2511. X#endif
  2512. X#endif
  2513. X
  2514. X#if    defined(HPUX8)
  2515. X    char *c, *s;
  2516. X    int i;
  2517. X    struct pst_status ps;
  2518. X#endif
  2519. X
  2520. X#if    defined(HPUX7)
  2521. X/*
  2522. X * Read the HP-UX 7.x user area from the swap file or memory.
  2523. X */
  2524. X    if ((p->p_flag & SLOAD) == 0) {
  2525. X
  2526. X    /*
  2527. X     * If the process is not loaded, read the user area from the swap file.
  2528. X     */
  2529. X        sw = (long)p->p_swaddr;
  2530. X
  2531. X#if    defined(hp9000s800)
  2532. X        sw += (long)ctod(btoc(STACKSIZE * NBPG));
  2533. X#endif
  2534. X
  2535. X        if (lseek(Swap, (off_t)dtob(sw), L_SET) == (off_t)-1
  2536. X        ||  read(Swap, u, U_SIZE) != U_SIZE)
  2537. X            return(1);
  2538. X        return(0);
  2539. X    }
  2540. X
  2541. X/*
  2542. X * Read the HP-UX 7.x user area via the page table.
  2543. X */
  2544. X
  2545. X#if    defined(hp9000s300)
  2546. X    pte_off = (off_t) &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
  2547. X    if (kread(pte_off, (char *)&pte1, sizeof(pte1)))
  2548. X        return(1);
  2549. X    pte_addr = (off_t) (ctob(pte1.pg_pfnum + 1)
  2550. X         - ((UPAGES + FLOAT) * sizeof(pte2)));
  2551. X    if (lseek(Mem, pte_addr, L_SET) == (off_t)-1
  2552. X    ||  read(Mem, (char *)&pte2, sizeof(pte2)) != sizeof(pte2))
  2553. X        return(1);
  2554. X    if (lseek(Mem, (off_t)ctob(pte2.pg_pfnum), L_SET) == (off_t)-1
  2555. X    ||  read(Mem, u, sizeof(struct user)) != sizeof(struct user))
  2556. X        return(1);
  2557. X#endif
  2558. X
  2559. X#if    defined(hp9000s800)
  2560. X    if (kread((off_t)uvadd((struct proc *)Procaddr),u,sizeof(struct user)))
  2561. X        return(1);
  2562. X#endif
  2563. X#endif    /* HPUX7 */
  2564. X
  2565. X#if    defined(HPUX8)
  2566. X/*
  2567. X * Use the undocumented HP-UX 8.x pstat() syscall to read process status.
  2568. X *
  2569. X * (HP won't release pstat(2) documentation to customers who have paid for
  2570. X * the inclusion of the syscall in HP-UX.  You figure that one out.)
  2571. X */
  2572. X    (void) bzero(u, U_SIZE);
  2573. X    if (pstat(PSTAT_PROC, &ps, sizeof(ps), 0, p->p_pid) != 1) {
  2574. X        (void) fprintf(stderr, "%s: can't pstat process %d: %s\n",
  2575. X            Pn, p->p_pid, sys_errlist[errno]);
  2576. X        return(1);
  2577. X    }
  2578. X/*
  2579. X * Scan the pst_cmd command buffer and skip to the last component of the
  2580. X * first path name.  Also skip any leading `-', signifying a login shell.
  2581. X * Copy the result to u_comm[].
  2582. X */
  2583. X    c = ps.pst_cmd;
  2584. X    ps.pst_cmd[PST_CLEN - 1] = '\0';    /* paranoia */
  2585. X    if (*c == '/') {
  2586. X        for (s = c; *s && *s != ' '; s++) {
  2587. X            if (*s == '/')
  2588. X                c = s + 1;
  2589. X        }
  2590. X    }
  2591. X    if (*c == '-')
  2592. X        c++;
  2593. X    for (i = 0; i < MAXCOMLEN; i++) {
  2594. X        if (*c == '\0' || *c == ' ' || *c == '/')
  2595. X            break;
  2596. X        u->u_comm[i] = *c++;
  2597. X    }
  2598. X    u->u_comm[i] = '\0';
  2599. X/*
  2600. X * Copy other process status values to the user area, as required.
  2601. X */
  2602. X#endif    /* HPUX8 */
  2603. X
  2604. X    return(0);
  2605. X}
  2606. X#endif
  2607. X
  2608. X
  2609. X/*
  2610. X * isfile() - is file selected for printing
  2611. X */
  2612. X
  2613. isfile(d, ty, ch, i)
  2614. X    dev_t d;            /* device */
  2615. X    enum vtype ty;            /* vnode type */
  2616. X
  2617. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun) 
  2618. X    int ch;                /* dummy */
  2619. X#endif
  2620. X
  2621. X#if    defined(_IBMR2)
  2622. X    chan_t ch;            /* gnode channel */
  2623. X#endif
  2624. X
  2625. X    long i;                 /* inode */
  2626. X
  2627. X/* ARGSUSED */
  2628. X
  2629. X{
  2630. X    int f;
  2631. X    struct sfile *s;
  2632. X
  2633. X    for (f = 0, s = Sfile; s; s = s->next) {
  2634. X
  2635. X#if    defined(_IBMR2)
  2636. X    /*
  2637. X     * Check for a regular AIX multiplexed file.  Match the channel if
  2638. X     * it was supplied.
  2639. X     */
  2640. X        if (s->type && s->mode == S_IFCHR && d == s->dev
  2641. X        && ty == VMPC) {
  2642. X            if (s->ch < 0 || (s->ch >= 0 && ch == s->ch)) {
  2643. X                f = 1;
  2644. X                break;
  2645. X            }
  2646. X        }
  2647. X#endif
  2648. X
  2649. X#if    defined(sun)
  2650. X    /*
  2651. X     * Check for a Sun clone file.
  2652. X     */
  2653. X        if (Vtype == V_STREAM && major(s->dev) == CLONEMAJ
  2654. X        && major(d) == minor(s->dev)) {
  2655. X            f = 1;
  2656. X            break;
  2657. X        }
  2658. X#endif
  2659. X
  2660. X    /*
  2661. X     * Check for a regular file or directory -- the device and
  2662. X     * inode numbers must match.
  2663. X     */
  2664. X        if (s->type) {
  2665. X            if (d == s->dev && (ino_t)i == s->i) {
  2666. X                f = 1;
  2667. X                break;
  2668. X            }
  2669. X            continue;
  2670. X        }
  2671. X    /*
  2672. X     * Check for a file system match.
  2673. X     * Try to avoid matching VCHR files to non-character devices.
  2674. X     */
  2675. X        if (d == s->dev) {
  2676. X            if ( ! (ty == VCHR && s->mode != S_IFCHR)) {
  2677. X                f = 1;
  2678. X                break;
  2679. X            }
  2680. X        }
  2681. X    }
  2682. X/*
  2683. X * Convert the name if a match occurred.
  2684. X */
  2685. X    if (f) {
  2686. X        (void) strcpy(Namech, s->name);
  2687. X
  2688. X#if    defined(_IBMR2)
  2689. X        if (ty == VMPC && s->ch < 0)
  2690. X            (void) sprintf(endnm(), "/%d", ch);
  2691. X#endif
  2692. X
  2693. X        if (s->devnm)
  2694. X            (void) sprintf(endnm(), " (%s)", s->devnm);
  2695. X        s->f = 1;
  2696. X        return(1);
  2697. X    }
  2698. X    return(0);
  2699. X}
  2700. X
  2701. X
  2702. X#if    defined(_IBMR2)
  2703. X/*
  2704. X * isglocked() - is a gnode locked
  2705. X */
  2706. X
  2707. char
  2708. isglocked(ga)
  2709. X    struct gnode *ga;        /* local gnode address */
  2710. X{
  2711. X
  2712. X    struct filock f;
  2713. X    off_t l;
  2714. X
  2715. X    if (ga->gn_filocks == NULL)
  2716. X        return(' ');
  2717. X    if (kread((off_t)ga->gn_filocks, &f, sizeof(f)))
  2718. X        return(' ');
  2719. X    if (f.set.l_whence == 0 && f.set.l_start == 0 && f.set.l_len == MAXEND)
  2720. X        l = 1;
  2721. X    else
  2722. X        l = 0;
  2723. X    switch (f.set.l_type & (F_RDLCK | F_WRLCK)) {
  2724. X
  2725. X    case F_RDLCK:
  2726. X        return((l) ? 'R' : 'r');
  2727. X    case F_WRLCK:
  2728. X        return((l) ? 'W' : 'w');
  2729. X    case (F_RDLCK + F_WRLCK):
  2730. X        return('*');
  2731. X    }
  2732. X    return(' ');
  2733. X}
  2734. X#endif
  2735. X
  2736. X
  2737. X/*
  2738. X * kread() - read from kernel memory
  2739. X */
  2740. X
  2741. int
  2742. kread(addr, buf, len)
  2743. X    off_t addr;            /* kernel memory address */
  2744. X    char *buf;            /* buffer to receive data */
  2745. X    int len;            /* length to read */
  2746. X{
  2747. X    int br;
  2748. X
  2749. X#if    defined(DYNIX) || defined(_IBMR2) || defined(hpux) || defined(NeXT)
  2750. X    if (lseek(Kmem, addr, L_SET) == (off_t)-1)
  2751. X        return(-1);
  2752. X    br = read(Kmem, buf, len);
  2753. X#endif
  2754. X
  2755. X#if    defined(sun)
  2756. X    br = kvm_read(Kd, (u_long)addr, buf, len);
  2757. X#endif
  2758. X
  2759. X    return((br == len) ? 0 : 1);
  2760. X}
  2761. X
  2762. X
  2763. X/*
  2764. X * printchdevname() - print character device name
  2765. X */
  2766. X
  2767. void
  2768. printchdevname(rdev, chan)
  2769. X    dev_t rdev;            /* device */
  2770. X
  2771. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2772. X    int chan;            /* dummy */
  2773. X#endif
  2774. X
  2775. X#if    defined(_IBMR2)
  2776. X    chan_t chan;            /* channel */
  2777. X#endif
  2778. X
  2779. X/* ARGSUSED */
  2780. X
  2781. X{
  2782. X
  2783. X#if    defined(sun)
  2784. X    struct clone *c;
  2785. X#endif
  2786. X
  2787. X    int low, hi, mid;
  2788. X    struct dev *dp;
  2789. X
  2790. X
  2791. X#if    defined(sun)
  2792. X/*
  2793. X * If this is a SunOS stream vnode, search for the clone parent.
  2794. X */
  2795. X    if (Vtype == V_STREAM && Clone) {
  2796. X        for (c = Clone; c; c = c->next) {
  2797. X            dp = c->dp;
  2798. X            if (major(rdev) == minor(dp->rdev))
  2799. X                goto found_device;
  2800. X        }
  2801. X    }
  2802. X#endif
  2803. X
  2804. X    low = mid = 0;
  2805. X    hi = Ndev - 1;
  2806. X        while (low <= hi) {
  2807. X                mid = (low + hi) / 2;
  2808. X        dp = Sdev[mid];
  2809. X        if ((long)rdev < (long)dp->rdev)
  2810. X            hi = mid - 1;
  2811. X        else if ((long)rdev > (long)dp->rdev)
  2812. X                        low = mid + 1;
  2813. X                else {
  2814. X
  2815. X#if    defined(sun)
  2816. X
  2817. found_device:
  2818. X
  2819. X#endif
  2820. X
  2821. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2822. X            (void) strcpy(Namech, dp->name);
  2823. X#endif
  2824. X
  2825. X#if    defined(_IBMR2)
  2826. X            if (chan < 0)
  2827. X                (void) strcpy(Namech, dp->name);
  2828. X            else
  2829. X                (void) sprintf(Namech, "%s/%d", dp->name,
  2830. X                    chan);
  2831. X#endif
  2832. X
  2833. X            return;
  2834. X        }
  2835. X        }
  2836. X    (void) strcpy(Namech, "name unknown");
  2837. X}
  2838. X
  2839. X
  2840. X#if    defined(DTYPE_GNODE)
  2841. X/*
  2842. X * printdevice() - print device file
  2843. X */
  2844. X
  2845. printdevice(va)
  2846. X    caddr_t va;            /* vnode's kernel address */
  2847. X{
  2848. X    struct vnode v;
  2849. X
  2850. X    if (readvnode(va, &v)) {
  2851. X                printline();
  2852. X                return;
  2853. X        }
  2854. X    (void) strcpy(Type, "dev");
  2855. X    printline();
  2856. X}
  2857. X#endif
  2858. X
  2859. X
  2860. X/*
  2861. X * printfile() - print file information
  2862. X */
  2863. X
  2864. void
  2865. printfile(fp)
  2866. X    struct file *fp;        /* kernel file table address */
  2867. X{
  2868. X    struct file f;
  2869. X
  2870. X    if (kread((off_t) fp, (char *) &f, sizeof(f))) {
  2871. X        (void) sprintf(Namech, "can't read file struct from %#x", fp);
  2872. X    } else {
  2873. X        if (f.f_count) {
  2874. X            switch (f.f_type) {
  2875. X
  2876. X            case DTYPE_VNODE:
  2877. X                printvnode(f.f_data);
  2878. X                break;
  2879. X
  2880. X            case DTYPE_SOCKET:
  2881. X                printsocket((caddr_t)f.f_data);
  2882. X                break;
  2883. X
  2884. X#if    defined(DTYPE_GNODE)
  2885. X            case DTYPE_GNODE:
  2886. X                printdevice(f.f_data);
  2887. X                break;
  2888. X#endif
  2889. X
  2890. X            default:
  2891. X                (void) sprintf(Namech,
  2892. X                    "unknown file struct type %#x at %#x\n",
  2893. X                    f.f_type, fp);
  2894. X                printline();
  2895. X            }
  2896. X            return;
  2897. X        }
  2898. X    }
  2899. X    return;
  2900. X}
  2901. X
  2902. X
  2903. X/*
  2904. X * printinaddr() - print Internet address
  2905. X */
  2906. X
  2907. void
  2908. printinaddr(ia, p)
  2909. X    struct in_addr *ia;        /* Internet address */
  2910. X    u_short p;            /* port */
  2911. X{
  2912. X    unsigned char *u;
  2913. X
  2914. X    if (ia->s_addr == INADDR_ANY) {
  2915. X        (void) sprintf(endnm(), "*:%d", p);
  2916. X        return;
  2917. X    }
  2918. X    u = (unsigned char *) ia;
  2919. X    (void) sprintf(endnm(), "%u.%u.%u.%u:%u", u[0], u[1], u[2], u[3], p);
  2920. X}
  2921. X
  2922. X
  2923. X/*
  2924. X * printiproto() - print Internet protocol name
  2925. X */
  2926. X
  2927. void
  2928. printiproto(p)
  2929. X    int p;                /* protocol number */
  2930. X{
  2931. X    int i;
  2932. X    static int m = -1;
  2933. X    char *s;
  2934. X
  2935. X    switch(p) {
  2936. X
  2937. X#if    defined(IPPROTO_TCP)
  2938. X    case IPPROTO_TCP:
  2939. X        s = "TCP";
  2940. X        break;
  2941. X#endif
  2942. X
  2943. X#if    defined(IPPROTO_UDP)
  2944. X    case IPPROTO_UDP:
  2945. X        s = "UDP";
  2946. X        break;
  2947. X#endif
  2948. X
  2949. X#if    defined(IPPROTO_IP)
  2950. X    case IPPROTO_IP:
  2951. X        s = "IP";
  2952. X        break;
  2953. X#endif
  2954. X
  2955. X#if    defined(IPPROTO_ICMP)
  2956. X    case IPPROTO_ICMP:
  2957. X        s = "ICMP";
  2958. X        break;
  2959. X#endif
  2960. X
  2961. X#if    defined(IPPROTO_IGMP)
  2962. X    case IPPROTO_IGMP:
  2963. X        s = "IGMP";
  2964. X        break;
  2965. X#endif
  2966. X
  2967. X#if    defined(IPPROTO_GGP)
  2968. X    case IPPROTO_GGP:
  2969. X        s = "GGP";
  2970. X        break;
  2971. X#endif
  2972. X
  2973. X#if    defined(IPPROTO_EGP)
  2974. X    case IPPROTO_EGP:
  2975. X        s = "EGP";
  2976. X        break;
  2977. X#endif
  2978. X
  2979. X#if    defined(IPPROTO_PUP)
  2980. X    case IPPROTO_PUP:
  2981. X        s = "PUP";
  2982. X        break;
  2983. X#endif
  2984. X
  2985. X#if    defined(IPPROTO_IDP)
  2986. X    case IPPROTO_IDP:
  2987. X        s = "IDP";
  2988. X        break;
  2989. X#endif
  2990. X
  2991. X#if    defined(IPPROTO_ND)
  2992. X    case IPPROTO_ND:
  2993. X        s = "ND";
  2994. X        break;
  2995. X#endif
  2996. X
  2997. X#if    defined(IPPROTO_RAW)
  2998. X    case IPPROTO_RAW:
  2999. X        s = "RAW";
  3000. X        break;
  3001. X#endif
  3002. X
  3003. X#if    defined(IPPROTO_HELLO)
  3004. X    case IPPROTO_HELLO:
  3005. X        s = "HELLO";
  3006. X        break;
  3007. X#endif
  3008. X
  3009. X#if    defined(IPPROTO_PXP)
  3010. X    case IPPROTO_PXP:
  3011. X        s = "PXP";
  3012. X        break;
  3013. X#endif
  3014. X
  3015. X#if    defined(IPPROTO_RAWIP)
  3016. X    case IPPROTO_RAWIP:
  3017. X        s = "RAWIP";
  3018. X        break;
  3019. X#endif
  3020. X
  3021. X#if    defined(IPPROTO_RAWIF)
  3022. X    case IPPROTO_RAWIF:
  3023. X        s = "RAWIF";
  3024. X        break;
  3025. X#endif
  3026. X
  3027. X    default:
  3028. X        s = NULL;
  3029. X    }
  3030. X    if (s)
  3031. X        (void) sprintf(Iproto, "%*.*s", IPROTOL, IPROTOL, s);
  3032. X    else {    
  3033. X        if (m < 0) {
  3034. X            for (i = 0, m = 1; i < IPROTOL-1; i++)
  3035. X                m *= 10;
  3036. X        }
  3037. X        (void) sprintf(Iproto, "%d?", p % m);
  3038. X    }
  3039. X}
  3040. X
  3041. X
  3042. X/*
  3043. X * printline() - print output line
  3044. X */
  3045. X
  3046. void
  3047. printline()
  3048. X{
  3049. X    if (Fprint == 0)
  3050. X        return;
  3051. X    if (Fterse) {
  3052. X        (void) printf("%d\n", Pid);
  3053. X        return;
  3054. X    }
  3055. X    if (Hdr == 0) {
  3056. X
  3057. X#if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3058. X        (void) printf("COMMAND     PID     USER   FD  TYPE     DEVICE");
  3059. X#endif
  3060. X
  3061. X#if    defined(hpux)
  3062. X        (void) printf("COMMAND     PID     USER   FD  TYPE       DEVICE");
  3063. X#endif
  3064. X
  3065. X        if (Fsize)
  3066. X        (void) printf("     SIZE");
  3067. X        (void)printf("   INODE/NAME\n");
  3068. X    }
  3069. X    Hdr++;
  3070. X    (void) printf("%-9.9s%6d %8s %4s%c %4.4s ",
  3071. X            Command ? Command : "",
  3072. X            Pid,
  3073. X            User,
  3074. X            Fd,
  3075. X            Lock,
  3076. X            Type
  3077. X    );
  3078. X    if (Fdev)
  3079. X
  3080. X#if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3081. X        (void) printf(" %4d,%4d ", major(Dev), minor(Dev));
  3082. X#endif
  3083. X
  3084. X#if    defined(hpux)
  3085. X        (void) printf("%3d,0x%06x ", major(Dev), minor(Dev));
  3086. X#endif
  3087. X
  3088. X    else {
  3089. X        if (Devch[0])
  3090. X
  3091. X#if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3092. X            (void) printf("%s ", Devch);
  3093. X        else
  3094. X            (void) printf("           ");
  3095. X#endif
  3096. X
  3097. X#if    defined(hpux)
  3098. X            (void) printf("  %s ", Devch);
  3099. X        else
  3100. X            (void) printf("             ");
  3101. X#endif
  3102. X
  3103. X    }
  3104. X    if (Fsize) {
  3105. X        if (Size_def)
  3106. X            (void) printf("%8d ", Size);
  3107. X        else
  3108. X            (void) printf("         ");
  3109. X    }
  3110. X    if (Inode >= 0)
  3111. X        (void) printf("%7ld ", Inode);
  3112. X    else if (Inode == -2l) {
  3113. X        if (Iproto[0] == '\0')
  3114. X            (void) printf("%7s ", "");
  3115. X        else
  3116. X            (void) printf("%7.7s ", Iproto);
  3117. X    }
  3118. X    (void) printf("%s\n", Namech);
  3119. X}
  3120. X
  3121. X
  3122. X/*
  3123. X * printsocket() - print socket
  3124. X */
  3125. X
  3126. void
  3127. printsocket(sa)
  3128. X    caddr_t sa;            /* socket address in kernel */
  3129. X{
  3130. X    int fam;
  3131. X
  3132. X#if    defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3133. X    struct domain d;
  3134. X#endif
  3135. X
  3136. X#if    defined(_IBMR2)
  3137. X    struct gnode g;
  3138. X    struct inode i;
  3139. X    int is = 0;
  3140. X    struct vnode v;
  3141. X#endif
  3142. X
  3143. X    struct inpcb inp;
  3144. X    struct mbuf mb;
  3145. X    struct protosw p;
  3146. X    struct socket s;
  3147. X    struct sockaddr_un *ua;
  3148. X    struct unpcb uc, unp;
  3149. X
  3150. X        (void) strcpy(Type, "sock");
  3151. X    Inode = -2l;
  3152. X    if (sa == NULL) {
  3153. X        (void) sprintf(Namech, "no socket address");
  3154. X        printline();
  3155. X        return;
  3156. X    }
  3157. X        if (kread((off_t) sa, (char *) &s, sizeof(s))) {
  3158. X                (void) sprintf(Namech, "can't read socket struct from %#x",
  3159. X            sa);
  3160. X                printline();
  3161. X                return;
  3162. X        }
  3163. X        if (s.so_proto == NULL
  3164. X    ||  kread((off_t) s.so_proto, (char *) &p, sizeof(p))) {
  3165. X                (void) strcpy(Namech, "no protocol switch");
  3166. X                printline();
  3167. X                return;
  3168. X        }
  3169. X
  3170. X#if    defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3171. X        if (kread((off_t) p.pr_domain, (char *) &d, sizeof(d))) {
  3172. X                (void) sprintf(Namech, "can't read domain struct from %#x",
  3173. X                        p.pr_domain);
  3174. X                printline();
  3175. X                return;
  3176. X        }
  3177. X#endif
  3178. X
  3179. X/*
  3180. X * Process socket by the associated domain family.
  3181. X */
  3182. X
  3183. X#if    defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3184. X    switch ((fam = d.dom_family))
  3185. X#endif
  3186. X
  3187. X#if    defined(HPUX7)
  3188. X    switch ((fam = p.pr_family))
  3189. X#endif
  3190. X
  3191. X    {
  3192. X    case AF_INET:
  3193. X        if (Fnet)
  3194. X            Fprint = 1;
  3195. X        (void) strcpy(Type, "inet");
  3196. X    /*
  3197. X     * Read Internet protocol control block.
  3198. X     */
  3199. X        if (s.so_pcb == NULL
  3200. X        || kread((off_t) s.so_pcb, (char *) &inp, sizeof(inp)))
  3201. X            return;
  3202. X        if ((struct socket *)sa != inp.inp_socket)
  3203. X            return;
  3204. X        printiproto(p.pr_protocol);
  3205. X        (void) sprintf(Devch, "0x%08x",
  3206. X                  (inp.inp_ppcb == NULL) ? s.so_pcb
  3207. X                             : inp.inp_ppcb);
  3208. X
  3209. X#if    defined(DYNIX)
  3210. X        printinaddr(&inp.inp_laddr, ntohs(inp.inp_lport));
  3211. X#endif
  3212. X
  3213. X#if    defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3214. X        printinaddr(&inp.inp_laddr, inp.inp_lport);
  3215. X#endif
  3216. X
  3217. X        if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) {
  3218. X            (void) strcat(endnm(), "->");
  3219. X
  3220. X#if    defined(DYNIX)
  3221. X        printinaddr(&inp.inp_faddr, ntohs(inp.inp_fport));
  3222. X#endif
  3223. X
  3224. X#if    defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3225. X            printinaddr(&inp.inp_faddr, inp.inp_fport);
  3226. X#endif
  3227. X
  3228. X        }
  3229. X        break;
  3230. X
  3231. X    case AF_UNIX:
  3232. X        if (Funix)
  3233. X            Fprint = 1;
  3234. X        (void) strcpy(Type, "unix");
  3235. X    /*
  3236. X     * Read Unix protocol control block and the Unix address structure.
  3237. X     */
  3238. X
  3239. X        (void) sprintf(Devch, "0x%08x", sa);
  3240. X        if (kread((off_t) s.so_pcb, (char *) &unp, sizeof(unp))) {
  3241. X            (void) sprintf(Namech, "can't read unpcb at %#x",
  3242. X                s.so_pcb);
  3243. X            break;
  3244. X        }
  3245. X        if ((struct socket *)sa != unp.unp_socket) {
  3246. X            (void) sprintf(Namech, "unp_socket (%#x) mismatch",
  3247. X                unp.unp_socket);
  3248. X            break;
  3249. X        }
  3250. X        if (unp.unp_addr) {
  3251. X            if (kread((off_t) unp.unp_addr, (char *) &mb, sizeof(mb))) {
  3252. X            (void) sprintf(Namech,
  3253. X                "can't read unp_addr at %#x",
  3254. X                unp.unp_addr);
  3255. X            break;
  3256. X            }
  3257. X            ua = (struct sockaddr_un *)(((char *)&mb) + mb.m_off);
  3258. X        } else {
  3259. X            ua = (struct sockaddr_un *)&mb;
  3260. X            (void) bzero((char *)ua, sizeof(struct sockaddr_un));
  3261. X            ua->sun_family = AF_UNSPEC;
  3262. X        }
  3263. X    /*
  3264. X     * Print information on Unix socket that has no address bound
  3265. X     * to it, although it may be connected to another Unix domain
  3266. X     * socket as a pipe.
  3267. X     */
  3268. X        if (ua->sun_family != AF_UNIX) {
  3269. X            if (ua->sun_family == AF_UNSPEC) {
  3270. X                if (unp.unp_conn) {
  3271. X                    if (kread((off_t) unp.unp_conn,
  3272. X                        (char *) &uc, sizeof(uc))) {
  3273. X                        (void) sprintf(Namech,
  3274. X                        "can't read unp_conn at %#x",
  3275. X                        unp.unp_conn);
  3276. X                    } else {
  3277. X                        (void) sprintf(Namech,
  3278. X                        "->0x%08x", uc.unp_socket);
  3279. X                    }
  3280. X                } else
  3281. X                    (void) strcpy(Namech, "->(none)");
  3282. X            } else
  3283. X                (void) sprintf(Namech,
  3284. X                    "unknown sun_family (%d)",
  3285. X                    ua->sun_family);
  3286. X            break;
  3287. X        }
  3288. X
  3289. X#if    defined(_IBMR2)
  3290. X    /*
  3291. X     * Read any associated vnode and then read its gnode and inode.
  3292. X     */
  3293. X        g.gn_type = VSOCK;
  3294. X        if (unp.unp_vnode && readvnode(unp.unp_vnode, &v) == 0) {
  3295. X            if (v.v_gnode && readgnode(v.v_gnode, &g) == 0) {
  3296. X                Lock = isglocked(&g);
  3297. X                if (g.gn_type == VSOCK && g.gn_data
  3298. X                && readinode(g.gn_data, &i) == 0)
  3299. X                    is = 1;
  3300. X            }
  3301. X        }
  3302. X    /*
  3303. X     * Print Unix socket information.
  3304. X     */
  3305. X        if (is) {
  3306. X            Dev = i.i_dev;
  3307. X            Fdev = 1;
  3308. X            Devch[0] = '\0';
  3309. X            Inode = (long)i.i_number;
  3310. X        }
  3311. X#endif
  3312. X
  3313. X        (void) sprintf(Namech, "%.*s",
  3314. X            mb.m_len - sizeof(ua->sun_family),
  3315. X            ua->sun_path[0] ? ua->sun_path : "no address");
  3316. X        break;
  3317. X
  3318. X    default:
  3319. X        (void) sprintf(Namech, "unknown family %#x", fam);
  3320. X    }
  3321. X    printline();
  3322. X}
  3323. X
  3324. X
  3325. X/*
  3326. X * printuid() - print User ID or login name
  3327. X */
  3328. X
  3329. void
  3330. printuid(u)
  3331. X    uid_t u;            /* User ID number */
  3332. X{
  3333. X    static int p = 0;
  3334. X    static uid_t pu;
  3335. X    struct passwd *pw;
  3336. X
  3337. X    if (p && u == pu)
  3338. X        return;
  3339. X    p = 1;
  3340. X    pu = u;
  3341. X    if (Futol && (pw = getpwuid(u)) != NULL)
  3342. X        (void) sprintf(User, "%*.*s", USERPRTL, USERPRTL, pw->pw_name);
  3343. X    else
  3344. X        (void) sprintf(User, "%*d", USERPRTL, u);
  3345. X}
  3346. X
  3347. X
  3348. X/*
  3349. X * printvnode() - print vnode
  3350. X */
  3351. X
  3352. void
  3353. printvnode(va)
  3354. X    caddr_t va;            /* vnode kernel space address */
  3355. X{
  3356. X
  3357. X    dev_t dev;
  3358. X    struct inode i;
  3359. X    int prdev;
  3360. X    struct rnode r;
  3361. X    char *ty;
  3362. X    enum vtype type;
  3363. X    struct vnode v;
  3364. X    struct l_vfs *vfs;
  3365. X
  3366. X#if    defined(NeXT)
  3367. X    struct vnode rv;
  3368. X    struct snode s;
  3369. X#endif
  3370. X
  3371. X#if    defined(_IBMR2)
  3372. X    struct cdrnode c;
  3373. X    struct gnode g;
  3374. X#endif
  3375. X
  3376. X#if    defined(sun)
  3377. X    struct fifonode f;
  3378. X    struct vnode rv;
  3379. X    struct snode s;
  3380. X    struct tmpnode t;
  3381. X#endif
  3382. X
  3383. X/*
  3384. X * Read the vnode.
  3385. X */
  3386. X    if (readvnode((caddr_t)va, &v)) {
  3387. X                printline();
  3388. X                return;
  3389. X        }
  3390. X
  3391. X
  3392. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  3393. X/*
  3394. X * Determine the DYNIX, HP-UX, NeXT and SunOS vnode type.
  3395. X */
  3396. X    if ((unsigned long)v.v_op == Nl[X_NFS_OPS].n_value)
  3397. X        Vtype = V_NFS;
  3398. X
  3399. X#if    defined(sun)
  3400. X    else if ((unsigned long)v.v_op == Nl[X_TMP_OPS].n_value)
  3401. X        Vtype = V_TMP;
  3402. X#endif
  3403. X
  3404. X    else if (v.v_type == VFIFO)
  3405. X        Vtype = V_FIFO;
  3406. X
  3407. X#if    defined(sun)
  3408. X    else if (v.v_type == VCHR && !v.v_vfsp && v.v_stream)
  3409. X        Vtype = V_STREAM;
  3410. X#endif
  3411. X
  3412. X/*
  3413. X * Determine the DYNIX, HP-UX, NeXT or SunOS lock type.
  3414. X */
  3415. X    if (v.v_shlockc || v.v_exlockc) {
  3416. X        if (v.v_shlockc && v.v_exlockc)
  3417. X            Lock = '*';
  3418. X        else if (v.v_shlockc)
  3419. X            Lock = 'R';
  3420. X        else
  3421. X            Lock = 'W';
  3422. X    }
  3423. X#endif
  3424. X
  3425. X/*
  3426. X * Read the virtual file system structure.
  3427. X */
  3428. X    if ((vfs = readvfs(v.v_vfsp)) == NULL) {
  3429. X                (void) sprintf(Namech, "can't read vfs for %#x at %#x", v,
  3430. X            v.v_vfsp);
  3431. X                printline();
  3432. X        return;
  3433. X    }
  3434. X
  3435. X#if    defined(_IBMR2)
  3436. X/*
  3437. X * Determine the AIX vnode type.
  3438. X */
  3439. X    if (vfs->vmt_flags & MNT_REMOTE)
  3440. X        Vtype = V_NFS;
  3441. X/*
  3442. X * Read the AIX gnode and the associated inode or rnode.
  3443. X */
  3444. X
  3445. X    if (v.v_gnode) {
  3446. X        if (readgnode(v.v_gnode, &g)) {
  3447. X            printline();
  3448. X            return;
  3449. X        }
  3450. X    } else {
  3451. X        (void) sprintf(Namech, "vnode at %#x has no gnode\n", va);
  3452. X        printline();
  3453. X        return;
  3454. X    }
  3455. X    Lock = isglocked(&g);
  3456. X    if (Vtype == V_NFS) {
  3457. X        if (g.gn_data == NULL || readrnode(g.gn_data, &r)) {
  3458. X            (void) sprintf(Namech,
  3459. X                "remote gnode at %#x has no rnode", v.v_gnode);
  3460. X            printline();
  3461. X            return;
  3462. X        }
  3463. X    } else {
  3464. X        if (vfs->vmt_gfstype == MNT_CDROM) {
  3465. X            if (g.gn_data == NULL || readcdrnode(g.gn_data, &c)) {
  3466. X                (void) sprintf(Namech,
  3467. X                    "gnode at %#x has no cdrnode",
  3468. X                    v.v_gnode);
  3469. X                printline();
  3470. X                return;
  3471. X            }
  3472. X            i.i_number = c.cn_inumber;
  3473. X            i.i_size = (off_t)c.cn_size;
  3474. X        } else if (g.gn_data == NULL || readinode(g.gn_data, &i)) {
  3475. X            (void) sprintf(Namech, "gnode at %#x has no inode",
  3476. X                v.v_gnode);
  3477. X            printline();
  3478. X            return;
  3479. X        }
  3480. X    }
  3481. X#endif
  3482. X
  3483. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  3484. X/*
  3485. X * Read the DYNIX, HP-UX, NeXT or SunOS fifonode, inode, rnode, snode or
  3486. X * tmpnode.
  3487. X */
  3488. X    switch (Vtype) {
  3489. X    case V_NFS:
  3490. X        if (!v.v_data || readrnode((caddr_t)v.v_data, &r)) {
  3491. X            (void) sprintf(Namech,
  3492. X                "vnode at %#x: can't read rnode (%#x)",
  3493. X                va, v.v_data);
  3494. X            printline();
  3495. X            return;
  3496. X        }
  3497. X        break;
  3498. X
  3499. X#if    defined(sun)
  3500. X    case V_FIFO:
  3501. X
  3502. X    /*
  3503. X     * A Sun FIFO's vnode is linked to a fifonode.  The s_realvp
  3504. X     * pointer of the snode contained in the fifonode points to
  3505. X     * a vnode that points to the inode.  (Whew!)
  3506. X     */
  3507. X        if (!v.v_data || readfifonode(v.v_data, &f)) {
  3508. X            (void) sprintf(Namech,
  3509. X                "vnode at %#x: can't read fifonode (%#x)",
  3510. X                va, v.v_data);
  3511. X            printline();
  3512. X            return;
  3513. X        }
  3514. X        if (f.fn_snode.s_realvp) {
  3515. X            if (readvnode((caddr_t)f.fn_snode.s_realvp, &rv)) {
  3516. X                (void) sprintf(Namech,
  3517. X                "fifonode at %#x: can't read real vnode (%#x)",
  3518. X                v.v_data, f.fn_snode.s_realvp);
  3519. X                printline();
  3520. X                return;
  3521. X            }
  3522. X            if (!rv.v_data || readinode(rv.v_data, &i)) {
  3523. X                (void) sprintf(Namech,
  3524. X                    "fifonode at %#x: can't read inode (%#x)",
  3525. X                    v.v_data, rv.v_data);
  3526. X                printline();
  3527. X                return;
  3528. X            }
  3529. X        } else {
  3530. X            printline();
  3531. X            return;
  3532. X        }
  3533. X        break;
  3534. X    case V_STREAM:
  3535. X        if (!v.v_data || readsnode((caddr_t)v.v_data, &s)) {
  3536. X            (void) sprintf(Namech,
  3537. X                "vnode at %#x: can't read snode (%#x)",
  3538. X                va, v.v_data);
  3539. X            printline();
  3540. X            return;
  3541. X        }
  3542. X        break;
  3543. X    case V_TMP:
  3544. X        if (!v.v_data || readtnode((caddr_t)v.v_data, &t)) {
  3545. X            (void) sprintf(Namech,
  3546. X                "vnode at %#x: can't read tnode (%#x)",
  3547. X                va, v.v_data);
  3548. X            printline();
  3549. X            return;
  3550. X        }
  3551. X        break;
  3552. X#endif
  3553. X
  3554. X    case V_REG:
  3555. X    default:
  3556. X
  3557. X#if    defined(NeXT) || defined(sun)
  3558. X    /*
  3559. X     * NeXT and Sun VCHR vnodes point to an snode.  The snode's s_realvp
  3560. X     * usually points to a real vnode, which points to an inode.
  3561. X     */
  3562. X        if (v.v_type == VCHR) {
  3563. X            if (!v.v_data || readsnode(v.v_data, &s)) {
  3564. X                (void) sprintf(Namech,
  3565. X                    "vnode at %#x: can't read snode(%#x)",
  3566. X                    va, v.v_data);
  3567. X                printline();
  3568. X                return;
  3569. X            }
  3570. X            if (s.s_realvp) {
  3571. X                if (readvnode((caddr_t)s.s_realvp, &rv)) {
  3572. X                (void) sprintf(Namech,
  3573. X                    "snode at %#x: can't read real vnode (%#x)",
  3574. X                    v.v_data, s.s_realvp);
  3575. X                printline();
  3576. X                return;
  3577. X                }
  3578. X                if (!rv.v_data || readinode(rv.v_data, &i)) {
  3579. X                (void) sprintf(Namech,
  3580. X                    "snode at %#x: can't read inode (%#x)",
  3581. X                    v.v_data, rv.v_data);
  3582. X                printline();
  3583. X                return;
  3584. X                }
  3585. X            } else
  3586. X                (void) bzero((char *)&i, sizeof(i));
  3587. X            break;
  3588. X        }
  3589. X#endif
  3590. X
  3591. X        if (!v.v_data || readinode(v.v_data, &i)) {
  3592. X            (void) sprintf(Namech,
  3593. X                "vnode at %#x: can't read inode (%#x)",
  3594. X                va, v.v_data);
  3595. X            printline();
  3596. X            return;
  3597. X        }
  3598. X    }
  3599. X#endif
  3600. X
  3601. X/*
  3602. X * Get device and type for printing.
  3603. X */
  3604. X
  3605. X#if    defined(DYNIX)
  3606. X    switch(Vtype) {
  3607. X    case V_NFS:
  3608. X
  3609. X    /*
  3610. X     * Neither the rnode nor the vnode under DYNIX 3.0.12 contains the
  3611. X     * correct device number, so it's reclaimed (if possible) from the
  3612. X     * local, virtual file system table entry (put there by completevfs()
  3613. X     * from information placed in Mtab by readmnt()).
  3614. X     */
  3615. X        dev = vfs->dev;
  3616. X        break;
  3617. X    default:
  3618. X        dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  3619. X    }
  3620. X    type = v.v_type;
  3621. X    if (vfs->dir == NULL)
  3622. X        (void) completevfs(vfs, dev);
  3623. X#endif
  3624. X
  3625. X#if    defined(hpux)
  3626. X    if (Vtype == V_NFS)
  3627. X        dev = vfs->dev;
  3628. X    else
  3629. X        dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  3630. X    type = v.v_type;
  3631. X#endif
  3632. X
  3633. X#if    defined(_IBMR2)
  3634. X    if (Vtype == V_NFS)
  3635. X        dev = vfs->dev;
  3636. X    else
  3637. X        dev = g.gn_rdev;
  3638. X    type = g.gn_type;
  3639. X#endif
  3640. X
  3641. X#if    defined(NeXT)
  3642. X    switch (Vtype) {
  3643. X    case V_NFS:
  3644. X        dev = r.r_attr.va_fsid;
  3645. X        if (dev & 0x8000)
  3646. X            dev |= 0xff00;
  3647. X        break;
  3648. X    case V_REG:
  3649. X        dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  3650. X    }
  3651. X    type = v.v_type;
  3652. X    if (vfs->dir == NULL)
  3653. X        (void) completevfs(vfs, dev);
  3654. X#endif
  3655. X
  3656. X#if    defined(sun)
  3657. X    switch (Vtype) {
  3658. X    case V_NFS:
  3659. X        dev = r.r_attr.va_fsid;
  3660. X        break;
  3661. X    case V_STREAM:
  3662. X        dev = s.s_dev;
  3663. X        break;
  3664. X    case V_TMP:
  3665. X        dev = t.tn_attr.va_fsid;
  3666. X        break;
  3667. X    default:
  3668. X        dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  3669. X    }
  3670. X    type = v.v_type;
  3671. X    if (vfs->dir == NULL)
  3672. X        (void) completevfs(vfs, dev);
  3673. X#endif
  3674. X
  3675. X/*
  3676. X * Obtain the inode number.
  3677. X */
  3678. X
  3679. X#if    defined(DYNIX)
  3680. X    switch (Vtype) {
  3681. X    case V_NFS:
  3682. X        Inode = (long)r.r_nfsattr.na_nodeid;
  3683. X        break;
  3684. X    case V_FIFO:
  3685. X    case V_REG:
  3686. X        Inode = (long)i.i_number;
  3687. X    }
  3688. X#endif
  3689. X
  3690. X#if    defined(hpux)
  3691. X    switch (Vtype) {
  3692. X    case V_NFS:
  3693. X        Inode = (long)r.r_nfsattr.na_nodeid;
  3694. X        break;
  3695. X    case V_FIFO:
  3696. X    case V_REG:
  3697. X        Inode = (long)i.i_number;
  3698. X    }
  3699. X#endif
  3700. X
  3701. X#if    defined(_IBMR2)
  3702. X    Inode = (long)(Vtype == V_NFS) ? r.r_attr.va_serialno : i.i_number;
  3703. X#endif
  3704. X
  3705. X#if    defined(NeXT)
  3706. X    switch(Vtype) {
  3707. X    case V_NFS:
  3708. X        Inode = (long)r.r_attr.va_nodeid;
  3709. X        break;
  3710. X    case V_REG:
  3711. X        Inode = (long)i.i_number;
  3712. X    }
  3713. X#endif
  3714. X
  3715. X#if    defined(sun)
  3716. X    switch (Vtype) {
  3717. X    case V_NFS:
  3718. X        Inode = (long)r.r_attr.va_nodeid;
  3719. X        break;
  3720. X    case V_FIFO:
  3721. X    case V_REG:
  3722. X        Inode = (long)i.i_number;
  3723. X        break;
  3724. X    case V_TMP:
  3725. X        Inode = (long)t.tn_attr.va_nodeid;
  3726. X        break;
  3727. X    case V_STREAM:
  3728. X        Inode = -2l;
  3729. X    }
  3730. X#endif
  3731. X
  3732. X/*
  3733. X * Obtain the file size.
  3734. X */
  3735. X    switch (Vtype) {
  3736. X    case V_NFS:
  3737. X
  3738. X#if    defined(DYNIX) || defined(hpux)
  3739. X        Size = r.r_nfsattr.na_size;
  3740. X#endif
  3741. X
  3742. X#if    defined(_IBMR2) || defined(NeXT) || defined(sun)
  3743. X        Size = r.r_attr.va_size;
  3744. X#endif
  3745. X
  3746. X        Size_def = 1;
  3747. X        break;
  3748. X    case V_REG:
  3749. X        Size = i.i_size;
  3750. X        Size_def = 1;
  3751. X    }
  3752. X
  3753. X/*
  3754. X * Format the name characters.
  3755. X */
  3756. X    if (Vtype == V_NFS && Fnfs)
  3757. X        Fprint = 1;
  3758. X    (void) sprintf(Namech, "%s (%s)",
  3759. X        (vfs->dir) ? vfs->dir : "",
  3760. X        (vfs->fsname) ? vfs->fsname : "");
  3761. X/*
  3762. X * Test for specified file.
  3763. X */
  3764. X    prdev = 1;
  3765. X    if (Sfile && Fprint == 0) {
  3766. X
  3767. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  3768. X        Fprint = isfile(dev, type, 0, Inode);
  3769. X#endif
  3770. X
  3771. X#if    defined(_IBMR2)
  3772. X        Fprint = isfile(dev, type, g.gn_chan, Inode);
  3773. X#endif
  3774. X
  3775. X        if (Fprint == 0)
  3776. X            return;
  3777. X        prdev = 0;
  3778. X    }
  3779. X/*
  3780. X * Format the vnode type, and possibly the device name.
  3781. X */
  3782. X    switch (type) {
  3783. X
  3784. X    case VNON:
  3785. X        ty ="VNON";
  3786. X        break;
  3787. X    case VREG:
  3788. X    case VDIR:
  3789. X        ty = (type == VREG) ? "VREG" : "VDIR";
  3790. X        Fdev = 1;
  3791. X        Dev = dev;
  3792. X        break;
  3793. X    case VBLK:
  3794. X        ty = "VBLK";
  3795. X        break;
  3796. X    case VCHR:
  3797. X        Dev = dev;
  3798. X        Fdev = 1;
  3799. X        if (prdev)
  3800. X            (void) printchdevname(Dev, -1);
  3801. X        ty = "VCHR";
  3802. X        break;
  3803. X    case VLNK:
  3804. X        ty = "VLNK";
  3805. X        break;
  3806. X    case VSOCK:
  3807. X        ty = "SOCK";
  3808. X        break;
  3809. X    case VBAD:
  3810. X        ty = "VBAD";
  3811. X        break;
  3812. X    case VFIFO:
  3813. X        Dev = dev;
  3814. X        Fdev = 1;
  3815. X        ty = "FIFO";
  3816. X        break;
  3817. X
  3818. X#if    defined(_IBMR2)
  3819. X    case VMPC:
  3820. X        Dev = g.gn_rdev;
  3821. X        Fdev = 1;
  3822. X        Inode = -2l;
  3823. X        if (prdev)
  3824. X            (void) printchdevname(g.gn_rdev, g.gn_chan);
  3825. X        ty = "VMPC";
  3826. X        break;
  3827. X#endif
  3828. X
  3829. X    default:
  3830. X        (void) sprintf(Type, "%4d", type);
  3831. X        (void) strcpy(Namech, "unknown type");
  3832. X        ty = NULL;
  3833. X    }
  3834. X    if (ty)
  3835. X        (void) strcpy(Type, ty);
  3836. X/*
  3837. X * Print the line (at last) if printing has been selected.
  3838. X */
  3839. X    printline();
  3840. X}
  3841. X
  3842. X
  3843. X#if    defined(_IBMR2)
  3844. X/*
  3845. X * readcdrnode() - read CD-ROM node
  3846. X */
  3847. X
  3848. int
  3849. readcdrnode(ca, c)
  3850. X    caddr_t ca;            /* cdrnode kernel address */
  3851. X    struct cdrnode *c;        /* cdrnode buffer */
  3852. X{
  3853. X    if (kread((off_t)ca, (char *)c, sizeof(struct cdrnode))) {
  3854. X        (void) sprintf(Namech, "can't read cdrnode at %#x", ca);
  3855. X        return(1);
  3856. X    }
  3857. X    return(0);
  3858. X}
  3859. X#endif
  3860. X
  3861. X
  3862. X/*
  3863. X * readdev() - read names, modes and device types of everything in /dev
  3864. X */
  3865. X
  3866. void
  3867. readdev()
  3868. X{
  3869. X
  3870. X    DIR *dfp;
  3871. X    int dn = 0;
  3872. X    char **dstk = NULL;
  3873. X    int dx = 0;
  3874. X    int err = 0;
  3875. X    int i = 0;
  3876. X    MALLOC_S nl;
  3877. X    char path[MAXNAMLEN+1];
  3878. X    int pl;
  3879. X    struct stat sb;
  3880. X
  3881. X#if    defined(DYNIX) || defined(NeXT)
  3882. X    struct direct *dp;
  3883. X#endif
  3884. X
  3885. X#if    defined(hpux) || defined(_IBMR2) || defined(sun)
  3886. X    struct dirent *dp;
  3887. X#endif
  3888. X
  3889. X#if    defined(sun)
  3890. X    struct clone *c;
  3891. X#endif
  3892. X
  3893. X    (void) stkdir(&dstk, &dn, &dx, "/dev");
  3894. X/*
  3895. X * Unstack the next /dev or /dev/<subdirectory> directory.
  3896. X */
  3897. X    while (--dx >= 0) {
  3898. X        (void) strcpy(path, dstk[dx]);
  3899. X        if ((dfp = opendir(path)) == NULL) {
  3900. X            if (Fdevmsg)
  3901. X                (void) fprintf(stderr, "%s: can't open %s\n",
  3902. X                    Pn, path);
  3903. X            continue;
  3904. X        }
  3905. X        (void) strcat(path, "/");
  3906. X        pl = strlen(path);
  3907. X        (void) free((FREE_P *)dstk[dx]);
  3908. X        dstk[dx] = NULL;
  3909. X    /*
  3910. X     * Scan the directory.
  3911. X     */
  3912. X        for (dp = readdir(dfp); dp; dp = readdir(dfp)) {
  3913. X            if (dp->d_ino == 0 || dp->d_name[0] == '.')
  3914. X                continue;
  3915. X        /*
  3916. X         * Form the full path name and get its status.
  3917. X         */
  3918. X            if ((nl = pl + dp->d_namlen) >= sizeof(path)) {
  3919. X                (void) fprintf(stderr,
  3920. X                    "%s: /dev entry name too long: %s\n",
  3921. X                    Pn, dp->d_name);
  3922. X                exit(1);
  3923. X            }
  3924. X            (void) strncpy(&path[pl], dp->d_name,
  3925. X                      (STRNCPY_L)dp->d_namlen);
  3926. X            path[nl++] = '\0';
  3927. X            if (lstat(path, &sb) != 0) {
  3928. X                (void) fprintf(stderr,
  3929. X                    "%s: can't lstat %s: %s\n",
  3930. X                    Pn, path, sys_errlist[errno]);
  3931. X                err++;
  3932. X                continue;
  3933. X            }
  3934. X        /*
  3935. X         * If it's a subdirectory, stack its name for later
  3936. X         * processing.
  3937. X         */
  3938. X            if ((sb.st_mode & S_IFMT) == S_IFDIR) {
  3939. X                (void) stkdir(&dstk, &dn, &dx, path);
  3940. X                continue;
  3941. X            }
  3942. X        /*
  3943. X         * Skip all but character devices.
  3944. X         */
  3945. X            if ((sb.st_mode & S_IFMT) != S_IFCHR)
  3946. X                continue;
  3947. X        /*
  3948. X         * Make room for another Devtp[] entry.
  3949. X         */
  3950. X            if (i >= Ndev) {
  3951. X                Ndev += DEVINCR;
  3952. X                if (Devtp == NULL)
  3953. X                    Devtp = (struct dev *)malloc(
  3954. X                    (MALLOC_S)(sizeof(struct dev) * Ndev));
  3955. X                else
  3956. X                    Devtp = (struct dev *)realloc(
  3957. X                    (MALLOC_P *)Devtp,
  3958. X                    (MALLOC_S)(sizeof(struct dev)*Ndev));
  3959. X                if (Devtp == NULL) {
  3960. X                    (void) fprintf(stderr,
  3961. X                        "%s: no space for devices\n",
  3962. X                        Pn);
  3963. X                    exit(1);
  3964. X                }
  3965. X            }
  3966. X        /*
  3967. X         * Store the name and device number in the Devtp[] entry.
  3968. X         */
  3969. X            Devtp[i].rdev = sb.st_rdev;
  3970. X            if ((Devtp[i].name = (char *)malloc(nl)) == NULL) {
  3971. X                (void) fprintf(stderr,
  3972. X                    "%s: no space for /dev/%s\n",
  3973. X                    Pn, dp->d_name);
  3974. X                exit(1);
  3975. X            }
  3976. X            (void) strcpy(Devtp[i].name, path);
  3977. X
  3978. X#if    defined(sun)
  3979. X        /*
  3980. X         * Save the locations of the SunOS clone devices.
  3981. X         */
  3982. X            if (major(Devtp[i].rdev) == CLONEMAJ) {
  3983. X                if ((c =
  3984. X                   (struct clone *)malloc(sizeof(struct clone)))
  3985. X                == NULL) {
  3986. X                    (void) fprintf(stderr,
  3987. X                        "%s: no space for clone\n", Pn);
  3988. X                    exit(1);
  3989. X                }
  3990. X                c->dp = &Devtp[i];
  3991. X                c->next = Clone;
  3992. X                Clone = c;
  3993. X            }
  3994. X#endif
  3995. X
  3996. X            i++;
  3997. X        }
  3998. X        (void) closedir(dfp);
  3999. X    }
  4000. X/*
  4001. X * Free any directory stack space.
  4002. X */
  4003. X    if (dstk != NULL)
  4004. X        (void) free((FREE_P *)dstk);
  4005. X/*
  4006. X * Reduce the Devtp[] table to its minimum size.
  4007. X */
  4008. X    if (Ndev > i) {
  4009. X        Ndev = i;
  4010. X        Devtp = (struct dev *)realloc((MALLOC_P *)Devtp,
  4011. X              (MALLOC_S)(sizeof(struct dev) * Ndev));
  4012. X    }
  4013. X    if (err)
  4014. X        exit(1);
  4015. X/*
  4016. X * Allocate sorting pointers and sort them by Devtp[] device number.
  4017. X */
  4018. X    if ((Sdev = (struct dev **)malloc((MALLOC_S)(sizeof(struct dev *)
  4019. X        * Ndev)))
  4020. X    == NULL) {
  4021. X        (void) fprintf(stderr, "%s: no space for device pointers\n",
  4022. X            Pn);
  4023. X        exit(1);
  4024. X    }
  4025. X    for (i = 0; i < Ndev; i++) {
  4026. X        Sdev[i] = &Devtp[i];
  4027. X    }
  4028. X    (void) qsort((QSORT_P *)Sdev,(size_t)Ndev,(size_t)sizeof(struct dev *),
  4029. X        compdev);
  4030. X}
  4031. X
  4032. X
  4033. X#if    defined(sun)
  4034. X/*
  4035. X * readfifonode() - read fifonode
  4036. X */
  4037. X
  4038. int
  4039. readfifonode(fa, f)
  4040. X    caddr_t fa;            /* fifonode kernel address */
  4041. X    struct fifonode *f;        /* fifonode buffer */
  4042. X{
  4043. X    if (kread((off_t)fa, (char *)f, sizeof(struct fifonode))) {
  4044. X        (void) sprintf(Namech, "can't read fifonode at %#x", fa);
  4045. X        return(1);
  4046. X    }
  4047. X    return(0);
  4048. X}
  4049. X#endif
  4050. X
  4051. X
  4052. X#if    defined(_IBMR2)
  4053. X/*
  4054. X * readgnode() - read gnode
  4055. X */
  4056. X
  4057. int
  4058. readgnode(ga, g)
  4059. X    caddr_t ga;            /* gnode kernel address */
  4060. X    struct gnode *g;        /* gnode buffer */
  4061. X{
  4062. X    if (kread((off_t)ga, g, sizeof(struct gnode))) {
  4063. X        (void) sprintf(Namech, "can't read gnode at %#x", ga);
  4064. X        return(1);
  4065. X    }
  4066. X    return(0);
  4067. X}
  4068. X#endif
  4069. X
  4070. X
  4071. X/*
  4072. X * readinode() - read inode
  4073. X */
  4074. X
  4075. int
  4076. readinode(ia, i)
  4077. X    caddr_t ia;            /* inode kernel address */
  4078. X    struct inode *i;        /* inode buffer */
  4079. X{
  4080. X    if (kread((off_t)ia, (char *)i, sizeof(struct inode))) {
  4081. X        (void) sprintf(Namech, "can't read inode at %#x", ia);
  4082. X        return(1);
  4083. X    }
  4084. X    return(0);
  4085. X}
  4086. X
  4087. X
  4088. X#if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun) 
  4089. X/*
  4090. X * readmnt() - read mount table
  4091. X */
  4092. X
  4093. void
  4094. readmnt()
  4095. X{
  4096. X    int err = 0;
  4097. X    FILE *mfp;
  4098. X    struct mntent *mp;
  4099. X    struct mounts *mtp;
  4100. X    struct stat sb;
  4101. X
  4102. X        if ((mfp = setmntent(MOUNTED, "r")) == NULL) {
  4103. X                (void) fprintf(stderr, "%s: can't access %s\n", Pn, MOUNTED);
  4104. X                exit(1);
  4105. X        }
  4106. X        while ((mp = getmntent(mfp)) != NULL) {
  4107. X                if (statsafely(mp->mnt_dir, &sb, STATTMO))
  4108. X                        continue;
  4109. X        if ((mtp = (struct mounts *)malloc(sizeof(struct mounts)))
  4110. X        == NULL) {
  4111. X            err = 1;
  4112. X            break;
  4113. X        }
  4114. X        if ((mtp->dir = (char *)malloc(
  4115. X                (MALLOC_S)(strlen(mp->mnt_dir)+1)))
  4116. X        == NULL) {
  4117. X            err = 1;
  4118. X            break;
  4119. X        }
  4120. X        (void) strcpy(mtp->dir, mp->mnt_dir);
  4121. X        if ((mtp->fsname = (char *)malloc(
  4122. X                   (MALLOC_S)(strlen(mp->mnt_fsname)+1)))
  4123. X        == NULL) {
  4124. X            err = 1;
  4125. X            break;
  4126. X        }
  4127. X        (void) strcpy(mtp->fsname, mp->mnt_fsname);
  4128. X        mtp->next = Mtab;
  4129. X        mtp->dev = sb.st_dev;
  4130. X        mtp->inode = sb.st_ino;
  4131. X        mtp->mode = sb.st_mode;
  4132. X        mtp->rdev = sb.st_rdev;
  4133. X        Mtab = mtp;
  4134. X        }
  4135. X        (void) endmntent(mfp);
  4136. X    if (err) {
  4137. X        (void) fprintf(stderr, "%s: no space for mount at %s (%s)\n",
  4138. X            Pn, mp->mnt_fsname, mp->mnt_dir);
  4139. X        exit(1);
  4140. X    }
  4141. X}
  4142. X#endif
  4143. X
  4144. X
  4145. X#if    defined(_IBMR2)
  4146. X/*
  4147. X * readmnt() - read mount table
  4148. X */
  4149. X
  4150. void
  4151. readmnt()
  4152. X{
  4153. X    int err = 0;
  4154. X    char *dir, *fs, *h;
  4155. X    int fsl;
  4156. X    struct mounts *mtp;
  4157. X    int nm;
  4158. X    struct stat sb;
  4159. X    unsigned sz;
  4160. X    struct vmount *v, *vt;
  4161. X
  4162. X/*
  4163. X * Read the table of vmount structures.
  4164. X */
  4165. X    for (sz = sizeof(struct vmount);;) {
  4166. X        if ((vt = (struct vmount *)malloc(sz)) == NULL) {
  4167. X            (void) fprintf(stderr,
  4168. X                "%s: no space for vmount table\n", Pn);
  4169. X            exit(1);
  4170. X        }
  4171. X        nm = mntctl(MCTL_QUERY, sz, vt);
  4172. X        if (nm > 0) {
  4173. X            if (vt->vmt_revision != VMT_REVISION) {
  4174. X                (void) fprintf(stderr,
  4175. X                    "%s: stale file system, rev %d != %d\n",
  4176. X                    Pn, vt->vmt_revision, VMT_REVISION);
  4177. X                exit(1);
  4178. X            }
  4179. X            break;
  4180. X        }
  4181. X        if (nm == 0) {
  4182. X            sz = (unsigned)vt->vmt_revision;
  4183. X            (void) free((FREE_P *)vt);
  4184. X        } else {
  4185. X            (void) fprintf(stderr, "%s: mntctl error: %s\n",
  4186. X                Pn, sys_errlist[errno]);
  4187. X            exit(1);
  4188. X        }
  4189. X    }
  4190. X/*
  4191. X * Scan the vmount structures and build Mtab.
  4192. X */
  4193. X    for (v = vt; nm--; v = (struct vmount *)((char *)v + v->vmt_length)) {
  4194. X        dir = (char *)vmt2dataptr(v, VMT_STUB);
  4195. X        fs = (char *)vmt2dataptr(v, VMT_OBJECT);
  4196. X        h = (char *)vmt2dataptr(v, VMT_HOST);
  4197. X        fsl = strlen(fs);
  4198. X        if (v->vmt_flags & MNT_REMOTE)
  4199. X            fsl += strlen(h) + 1;
  4200. X                if (statsafely(dir, &sb, STATTMO))
  4201. X                        continue;
  4202. X        if ((mtp = (struct mounts *)malloc(sizeof(struct mounts)))
  4203. X        == NULL) {
  4204. X            err = 1;
  4205. X            break;
  4206. X        }
  4207. X        if ((mtp->dir = (char *)malloc(strlen(dir) + 1)) == NULL) {
  4208. X            err = 1;
  4209. X            break;
  4210. X        }
  4211. X        (void) strcpy(mtp->dir, dir);
  4212. X        if ((mtp->fsname = (char *)malloc(fsl + 1)) == NULL) {
  4213. X            err = 1;
  4214. X            break;
  4215. X        }
  4216. X        if (v->vmt_flags & MNT_REMOTE)
  4217. X            (void) sprintf(mtp->fsname, "%s:%s", h, fs);
  4218. X        else
  4219. X            (void) strcpy(mtp->fsname, fs);
  4220. X        mtp->dev = sb.st_dev;
  4221. X        mtp->inode = sb.st_ino;
  4222. X        mtp->mode = sb.st_mode;
  4223. X        mtp->rdev = sb.st_rdev;
  4224. X        mtp->next = Mtab;
  4225. X        Mtab = mtp;
  4226. X        }
  4227. X    if (err) {
  4228. X        (void) fprintf(stderr, "%s: no space for mount at %s (%s)\n",
  4229. X            Pn, fs, dir);
  4230. X        exit(1);
  4231. X    }
  4232. X    (void) free((FREE_P *)vt);
  4233. X}
  4234. X#endif
  4235. X
  4236. X
  4237. X/*
  4238. X * readrnode() - read rnode
  4239. X */
  4240. X
  4241. int
  4242. readrnode(ra, r)
  4243. X    caddr_t ra;            /* rnode kernel space address */
  4244. X    struct rnode *r;        /* rnode buffer pointer */
  4245. X{
  4246. X    if (kread((off_t)ra, (char *)r, sizeof(struct rnode))) {
  4247. X        (void) sprintf(Namech, "can't read rnode at %#x", ra);
  4248. X        return(1);
  4249. X    }
  4250. X    return(0);
  4251. X}
  4252. X
  4253. X
  4254. X#if    defined(NeXT) || defined(sun)
  4255. X/*
  4256. X * readsnode() - read snode
  4257. X */
  4258. X
  4259. int
  4260. readsnode(sa, s)
  4261. X    caddr_t sa;            /* snode kernel space address */
  4262. X    struct snode *s;        /* snode buffer pointer */
  4263. X{
  4264. X    if (kread((off_t)sa, (char *)s, sizeof(struct snode))) {
  4265. X        (void) sprintf(Namech, "can't read snode at %#x", sa);
  4266. X        return(1);
  4267. X    }
  4268. X    return(0);
  4269. X}
  4270. X#endif
  4271. X
  4272. X
  4273. X#if    defined(sun)
  4274. X/*
  4275. X * readtnode() - read tmpnode
  4276. X */
  4277. X
  4278. int
  4279. readtnode(ta, t)
  4280. X    caddr_t ta;            /* tmpnode kernel space address */
  4281. X    struct tmpnode *t;        /* tmpnode buffer pointer */
  4282. X{
  4283. X    if (kread((off_t)ta, (char *)t, sizeof(struct tmpnode))) {
  4284. X        (void) sprintf(Namech, "can't read tmpnode at %#x", ta);
  4285. X        return(1);
  4286. X    }
  4287. X    return(0);
  4288. X}
  4289. X#endif
  4290. X
  4291. X
  4292. X/*
  4293. X * readvfs() - read vfs structure
  4294. X */
  4295. X
  4296. struct l_vfs *
  4297. readvfs(va)
  4298. X    struct vfs *va;            /* vfs structure kernel address
  4299. X                     * - e. g., v.v_vfsp */
  4300. X{
  4301. X    struct vfs v;
  4302. X    struct l_vfs *vp;
  4303. X
  4304. X#if    defined(DYNIX) ||defined(hpux) || defined(sun)
  4305. X    struct mount m;
  4306. X#endif
  4307. X
  4308. X#if    defined(DYNIX) || defined(hpux)
  4309. X    struct mntinfo mi;
  4310. X#endif
  4311. X
  4312. X#if    defined(_IBMR2)
  4313. X    struct gfs g;
  4314. X    void *mp;
  4315. X    char *s1, *s2;
  4316. X    unsigned slen;
  4317. X    u_long ul;
  4318. X    struct vmount *vm;
  4319. X#endif
  4320. X
  4321. X    for (vp = Lvfs; vp; vp = vp->next) {
  4322. X        if (va == vp->addr)
  4323. X            return(vp);
  4324. X    }
  4325. X    if ((vp = (struct l_vfs *)malloc(sizeof(struct l_vfs))) == NULL) {
  4326. X        (void) fprintf(stderr, "%s: no space for vfs\n", Pn);
  4327. X        exit(1);
  4328. X    }
  4329. X
  4330. X#if    defined(DYNIX) || defined(hpux)
  4331. X    vp->dev = 0;
  4332. X#endif
  4333. X
  4334. X    vp->dir = NULL;
  4335. X    vp->fsname = NULL;
  4336. X
  4337. X#if    defined(sun)
  4338. X/*
  4339. X * SunOS vnodes of type VCHR that have a non-null v_stream pointer
  4340. X * represent streams and have no virtual file system pointer.
  4341. X */
  4342. X
  4343. X#endif
  4344. X
  4345. X#if    defined(DYNIX) ||defined(hpux) || defined(_IBMR2) || defined(NeXT)
  4346. X    if (!va)
  4347. X        goto vfs_exit;
  4348. X#endif
  4349. X
  4350. X    if (va && kread((off_t)va, (char *)&v, sizeof(v))) {
  4351. X
  4352. X#if    defined(DYNIX) || defined(hpux) || defined(_IBMR2) || defined(NeXT)
  4353. X
  4354. vfs_exit:
  4355. X
  4356. X#endif
  4357. X
  4358. X        (void) free((FREE_P *)vp);
  4359. X        return(NULL);
  4360. X    }
  4361. X
  4362. X#if    defined(_IBMR2)
  4363. X/*
  4364. X * Locate AIX mount information.
  4365. X */
  4366. X    if (kread((off_t) v.vfs_gfs, &g, sizeof(g)))
  4367. X        goto vfs_exit;
  4368. X    if (kread((off_t) v.vfs_mdata + sizeof(u_long), &ul, sizeof(ul)))
  4369. X        goto vfs_exit;
  4370. X    if ((mp = malloc((size_t) ul)) == NULL) {
  4371. X        (void) fprintf(stderr, "%s: no space for mount data\n", Pn);
  4372. X        exit(1);
  4373. X    }
  4374. X    if (kread((off_t) v.vfs_mdata, mp, (int) ul)) {
  4375. X        (void) free((FREE_P *)mp);
  4376. X        goto vfs_exit;
  4377. X    }
  4378. X    vm = (struct vmount *)mp;
  4379. X    vp->vmt_flags = vm->vmt_flags;
  4380. X    vp->vmt_gfstype = vm->vmt_gfstype;
  4381. X    vp->dev = (dev_t)vm->vmt_fsid.fsid_dev;
  4382. X    if ((s1 = vmt2dataptr(vm, VMT_STUB)) != NULL) {
  4383. X        if ((vp->dir = (char *)malloc(strlen(s1) + 1)) == NULL) {
  4384. X
  4385. readvfs_aix1:
  4386. X            (void) fprintf(stderr, "%s: readvfs, no space\n", Pn);
  4387. X            exit(1);
  4388. X        }
  4389. X        (void) strcpy(vp->dir, s1);
  4390. X    } else
  4391. X        vp->dir = NULL;
  4392. X    s1 = vmt2dataptr(vm, VMT_HOST);
  4393. X    if ((s2 = vmt2dataptr(vm, VMT_OBJECT)) == NULL || *s1 == '\0')
  4394. X        s2 = g.gfs_name;
  4395. X    if (s1 == NULL && s2 == NULL)
  4396. X        vp->fsname = NULL;
  4397. X    else {
  4398. X        slen = s2 ? strlen(s2) : 0;
  4399. X        if (vm->vmt_flags & MNT_REMOTE)
  4400. X            slen += (s1 ? strlen(s1) : 0) + 1;
  4401. X        if ((vp->fsname = (char *)malloc(slen + 1)) == NULL)
  4402. X            goto readvfs_aix1;
  4403. X        if (vm->vmt_flags & MNT_REMOTE)
  4404. X            (void) sprintf(vp->fsname, "%s:%s",
  4405. X                s1 ? s1 : "", s2 ? s2 : "");
  4406. X        else
  4407. X            (void) strcpy(vp->fsname, s2 ? s2 : "");
  4408. X    }
  4409. X    (void) free((FREE_P *)mp);
  4410. X#endif
  4411. X
  4412. X/*
  4413. X * Complete DYNIX, HP-UX and SunOS mount information.
  4414. X */
  4415. X
  4416. X#if    defined(DYNIX) || defined(hpux)
  4417. X    if (Vtype == V_NFS) {
  4418. X
  4419. X    /*
  4420. X     * DYNIX and HP-UX NFS vnode device values have a major number of 255.
  4421. X     * The minor number is a serial number found in the mntinfo
  4422. X     * structure to which the virtual file system's vfs_data points.
  4423. X     */ 
  4424. X        if (v.vfs_data
  4425. X        &&  kread((off_t)v.vfs_data, (char *)&mi, sizeof(mi)) == 0)
  4426. X            (void) completevfs(vp, makedev(255, mi.mi_mntno));
  4427. X    } else {
  4428. X        if (kread((off_t)v.vfs_data, (char *)&m, sizeof(m)) == 0)
  4429. X            (void) completevfs(vp, m.m_dev);
  4430. X    }
  4431. X#endif
  4432. X
  4433. X#if    defined(sun)
  4434. X    if (va && v.vfs_data && kread((off_t)v.vfs_data, (char *)&m, sizeof(m))
  4435. X    == 0)
  4436. X        (void) completevfs(vp, m.m_dev);
  4437. X#endif
  4438. X
  4439. X    vp->next = Lvfs;
  4440. X    vp->addr = va;
  4441. X    Lvfs = vp;
  4442. X    return(vp);
  4443. X}
  4444. X
  4445. X
  4446. X/*
  4447. X * readvnode() - read vnode
  4448. X */
  4449. X
  4450. int
  4451. readvnode(va, v)
  4452. X    caddr_t va;            /* vnode kernel space address */
  4453. X    struct vnode *v;        /* vnode buffer pointer */
  4454. X{
  4455. X    if (kread((off_t)va, (char *)v, sizeof(struct vnode))) {
  4456. X        (void) sprintf(Namech, "can't read vnode at %#x", va);
  4457. X        return(1);
  4458. X    }
  4459. X    return(0);
  4460. X}
  4461. X
  4462. X
  4463. X/*
  4464. X * statsafely() - stat path safely (i. e., with timeout)
  4465. X */
  4466. X
  4467. statsafely(path, buf, tm)
  4468. X        char *path;
  4469. X        struct stat *buf;
  4470. X        int tm;
  4471. X{
  4472. X        int err;
  4473. X        static int sverr;
  4474. X
  4475. X        if (tm == 0)
  4476. X                return(stat(path, buf));
  4477. X        sverr = errno;
  4478. X        if (setjmp(Tmo_jbuf)) {
  4479. X                (void) alarm(0);
  4480. X                (void) signal(SIGALRM, SIG_IGN);
  4481. X                errno = ETIMEDOUT;
  4482. X                return(-1);
  4483. X        }
  4484. X        (void) signal(SIGALRM, stattimeout);
  4485. X        (void) alarm((unsigned)tm);
  4486. X        err = stat(path, buf);
  4487. X        if (err != 0)
  4488. X                sverr = errno;
  4489. X        (void) alarm(0);
  4490. X        (void) signal(SIGALRM, SIG_IGN);
  4491. X        errno = sverr;
  4492. X        return(err);
  4493. X}
  4494. X
  4495. X
  4496. X/*
  4497. X * stattimeout() - time out a stat() call
  4498. X */
  4499. X
  4500. X#if    defined(DYNIX)
  4501. int
  4502. X#endif
  4503. X
  4504. X#if    defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  4505. void
  4506. X#endif
  4507. X
  4508. stattimeout()
  4509. X{
  4510. X        (void) alarm(0);
  4511. X        (void) signal(SIGALRM, SIG_IGN);
  4512. X        longjmp(Tmo_jbuf, 1);
  4513. X}
  4514. X
  4515. X
  4516. X/*
  4517. X * stkdir() - stack directory name
  4518. X */
  4519. X
  4520. void
  4521. stkdir(d, n, x, p)
  4522. X    char ***d;        /* array of directory pointers */
  4523. X    int *n;            /* number of pointers */
  4524. X    int *x;            /* current index */
  4525. X    char *p;        /* directory path */
  4526. X{
  4527. X    if (*d == NULL) {
  4528. X
  4529. X    /*
  4530. X     * Allocate first entry.
  4531. X     */
  4532. X        if ((*d = (char **)malloc(sizeof(char *))) == NULL) {
  4533. X
  4534. stkdir_nospace:
  4535. X
  4536. X            (void) fprintf(stderr,
  4537. X                "%s: no space for directory stack at %s\n",
  4538. X                Pn, p);
  4539. X            exit(1);
  4540. X        }
  4541. X        *n = 1;
  4542. X        *x = 0;
  4543. X    } else if (*x >= *n) {
  4544. X
  4545. X    /*
  4546. X     * Allocate additional space as required.
  4547. X     */
  4548. X        *n += 1;
  4549. X        if ((*d = (char **)realloc((MALLOC_P *)*d,
  4550. X                  (MALLOC_S)(*n * sizeof(char *))))
  4551. X        == NULL)
  4552. X            goto stkdir_nospace;
  4553. X    }
  4554. X/*
  4555. X * Allocate space for the name, copy it there and put its pointer on the stack.
  4556. X */
  4557. X    if (((*d)[*x] = (char *)malloc((MALLOC_S)(strlen(p) + 1))) == NULL) {
  4558. X        (void) fprintf(stderr, "%s: no space for %s\n", Pn, p);
  4559. X        exit(1);
  4560. X    }
  4561. X    (void) strcpy((*d)[*x], p);
  4562. X    *x += 1;
  4563. X}
  4564. END_OF_FILE
  4565. if test 79705 -ne `wc -c <'lsof.c'`; then
  4566.     echo shar: \"'lsof.c'\" unpacked with wrong size!
  4567. fi
  4568. # end of 'lsof.c'
  4569. fi
  4570. if test ! -d 'sys' ; then
  4571.     echo shar: Creating directory \"'sys'\"
  4572.     mkdir 'sys'
  4573. fi
  4574. if test -f 'sys/fss.h' -a "${1}" != "-c" ; then 
  4575.   echo shar: Will not clobber existing file \"'sys/fss.h'\"
  4576. else
  4577. echo shar: Extracting \"'sys/fss.h'\" \(0 characters\)
  4578. sed "s/^X//" >'sys/fss.h' <<'END_OF_FILE'
  4579. END_OF_FILE
  4580. if test 0 -ne `wc -c <'sys/fss.h'`; then
  4581.     echo shar: \"'sys/fss.h'\" unpacked with wrong size!
  4582. fi
  4583. # end of 'sys/fss.h'
  4584. fi
  4585. echo shar: End of shell archive.
  4586. exit 0
  4587.